From 0af73c2d197b5571038cf58e223273f704afcc46 Mon Sep 17 00:00:00 2001 From: Kali Date: Thu, 5 Jan 2023 14:11:44 +0100 Subject: [PATCH 01/94] fixed DNS via Proxy --- testssl.sh | 62 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/testssl.sh b/testssl.sh index 28e63ca..5041fc3 100755 --- a/testssl.sh +++ b/testssl.sh @@ -196,7 +196,7 @@ TESTSSL_INSTALL_DIR="${TESTSSL_INSTALL_DIR:-""}" # If you run testssl.sh and it CA_BUNDLES_PATH="${CA_BUNDLES_PATH:-""}" # You can have your CA stores some place else EXPERIMENTAL=${EXPERIMENTAL:-false} # a development hook which allows us to disable code PROXY_WAIT=${PROXY_WAIT:-20} # waiting at max 20 seconds for socket reply through proxy -DNS_VIA_PROXY=${DNS_VIA_PROXY:-true} # do DNS lookups via proxy. --ip=proxy reverses this +DNS_VIA_PROXY=${DNS_VIA_PROXY:-false} # do DNS lookups via proxy. --ip=proxy reverses this IGN_OCSP_PROXY=${IGN_OCSP_PROXY:-false} # Also when --proxy is supplied it is ignored when testing for revocation via OCSP via --phone-out HEADER_MAXSLEEP=${HEADER_MAXSLEEP:-5} # we wait this long before killing the process to retrieve a service banner / http header MAX_SOCKET_FAIL=${MAX_SOCKET_FAIL:-2} # If this many failures for TCP socket connects are reached we terminate @@ -22014,12 +22014,19 @@ display_rdns_etc() { datebanner() { local scan_time_f="" - + local node_banner="" + + if [[ -n "PROXY" ]] && $DNS_VIA_PROXY;then + node_banner="$NODE:$PORT" + else + node_banner="$NODEIP:$PORT ($NODE)" + fi + if [[ "$1" =~ Done ]] ; then scan_time_f="$(printf "%04ss" "$SCAN_TIME")" # 4 digits because of windows - pr_reverse "$1 $(date +%F) $(date +%T) [$scan_time_f] -->> $NODEIP:$PORT ($NODE) <<--" + pr_reverse "$1 $(date +%F) $(date +%T) [$scan_time_f] -->> $node_banner <<--" else - pr_reverse "$1 $(date +%F) $(date +%T) -->> $NODEIP:$PORT ($NODE) <<--" + pr_reverse "$1 $(date +%F) $(date +%T) -->> $node_banner <<--" fi outln "\n" [[ "$1" =~ Start ]] && display_rdns_etc @@ -23735,7 +23742,6 @@ lets_roll() { fi stopwatch initialized - [[ -z "$NODEIP" ]] && fatal "$NODE doesn't resolve to an IP address" $ERR_DNSLOOKUP nodeip_to_proper_ip6 reset_hostdepended_vars determine_rdns # Returns always zero or has already exited if fatal error occurred @@ -23938,26 +23944,30 @@ lets_roll() { [[ -z "$NODE" ]] && parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDRs and IP46ADDR is set now prepare_logging - if ! determine_ip_addresses; then - fatal "No IP address could be determined" $ERR_DNSLOOKUP - fi - if [[ $(count_words "$IPADDRs") -gt 1 ]]; then # we have more than one ipv4 address to check - MULTIPLE_CHECKS=true - pr_bold "Testing all IPv4 addresses (port $PORT): "; outln "$IPADDRs" - for ip in $IPADDRs; do - draw_line "-" $((TERM_WIDTH * 2 / 3)) - outln - NODEIP="$ip" - lets_roll "${STARTTLS_PROTOCOL}" - RET=$((RET + $?)) # RET value per IP address - done - draw_line "-" $((TERM_WIDTH * 2 / 3)) - outln - pr_bold "Done testing now all IP addresses (on port $PORT): "; outln "$IPADDRs" - else # Just 1x ip4v to check, applies also if CMDLINE_IP was supplied - NODEIP="$IPADDRs" - lets_roll "${STARTTLS_PROTOCOL}" - RET=$? - fi + if [[ -n "$PROXY" ]] && $DNS_VIA_PROXY; then + NODEIP="$NODE" + lets_roll "${STARTTLS_PROTOCOL}" + RET=$? + else + determine_ip_addresses + if [[ $(count_words "$IPADDRs") -gt 1 ]]; then # we have more than one ipv4 address to check + MULTIPLE_CHECKS=true + pr_bold "Testing all IPv4 addresses (port $PORT): "; outln "$IPADDRs" + for ip in $IPADDRs; do + draw_line "-" $((TERM_WIDTH * 2 / 3)) + outln + NODEIP="$ip" + lets_roll "${STARTTLS_PROTOCOL}" + RET=$((RET + $?)) # RET value per IP address + done + draw_line "-" $((TERM_WIDTH * 2 / 3)) + outln + pr_bold "Done testing now all IP addresses (on port $PORT): "; outln "$IPADDRs" + else # Just 1x ip4v to check, applies also if CMDLINE_IP was supplied + NODEIP="$IPADDRs" + lets_roll "${STARTTLS_PROTOCOL}" + RET=$? + fi + fi exit $RET From 8ae8a6fc44feb9f21adf92dcffbbc324e71f84d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 00:03:02 +0000 Subject: [PATCH 02/94] Bump docker/build-push-action from 3.3.0 to 4.0.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3.3.0 to 4.0.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v3.3.0...v4.0.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-3.1dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-3.1dev.yml b/.github/workflows/docker-3.1dev.yml index 145d77c..62fd15c 100644 --- a/.github/workflows/docker-3.1dev.yml +++ b/.github/workflows/docker-3.1dev.yml @@ -48,7 +48,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v3.3.0 + uses: docker/build-push-action@v4.0.0 with: push: ${{ github.event_name != 'pull_request' }} context: . From 2e0898c9ef18ffb4604e9d493d6cbb2588ed4a3c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Tue, 31 Jan 2023 09:34:18 +0100 Subject: [PATCH 03/94] Remove NNTP from CI tests Maybe for the future we should check whether host is available and if so then run the test --- t/21_baseline_starttls.t | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/t/21_baseline_starttls.t b/t/21_baseline_starttls.t index 79d90e2..8778b98 100755 --- a/t/21_baseline_starttls.t +++ b/t/21_baseline_starttls.t @@ -156,15 +156,13 @@ unlike($openssl_out, qr/$openssl_regex_bl/, ""); $tests++; +# For NNTP there doesn't seem to be reliable host out there +#$uri="144.76.182.167:119"; -$uri="144.76.182.167:119"; - -# unlink "tmp.json"; -printf "\n%s\n", "STARTTLS NNTP unit tests via sockets --> $uri ..."; -$socket_out = `./testssl.sh $check2run -t nntp $uri 2>&1`; -# $socket_json = json('tmp.json'); -unlike($socket_out, qr/$socket_regex_bl/, ""); -$tests++; +#printf "\n%s\n", "STARTTLS NNTP unit tests via sockets --> $uri ..."; +#$socket_out = `./testssl.sh $check2run -t nntp $uri 2>&1`; +#unlike($socket_out, qr/$socket_regex_bl/, ""); +#$tests++; # commented out, bc of travis' limits # From beb94d9efc159311c438a7963cc0d5b394c56e7b Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Wed, 1 Feb 2023 19:40:40 +0100 Subject: [PATCH 04/94] Upgrade Alpine version for both Dockerfiles ... to improve/mitigate performance problems, see #2299. (musl libc vs. glibc) --- Dockerfile | 2 +- Dockerfile.git | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index e053099..2ccf505 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.16 +FROM alpine:3.17 RUN apk update && \ apk upgrade && \ diff --git a/Dockerfile.git b/Dockerfile.git index 4ea8a5c..6411a17 100644 --- a/Dockerfile.git +++ b/Dockerfile.git @@ -1,6 +1,6 @@ # Build using git repo -FROM alpine:3.16 +FROM alpine:3.17 WORKDIR /home/testssl From 74892e45c5d88dd03ab262a29fe52d16269615f7 Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Tue, 31 Jan 2023 19:58:17 +1300 Subject: [PATCH 05/94] chore: Use a single `COPY` by better leveraging `.dockerignore` patterns --- .dockerignore | 9 +++++++++ Dockerfile | 5 ++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.dockerignore b/.dockerignore index 7cd827c..bbc4f67 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,11 @@ +# Exclude everything from the Docker build context: +* + +# Except for this content: +!bin/ +!etc/ +!testssl.sh + +# But additionally exclude this nested content: bin/openssl.Darwin.* bin/openssl.FreeBSD.* diff --git a/Dockerfile b/Dockerfile index 2ccf505..49b3553 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,9 +12,8 @@ RUN apk update && \ USER testssl WORKDIR /home/testssl/ -COPY --chown=testssl:testssl etc/. /home/testssl/etc/ -COPY --chown=testssl:testssl bin/. /home/testssl/bin/ -COPY --chown=testssl:testssl testssl.sh /home/testssl/ +# Copy over build context (after filtered by .dockerignore): bin/ etc/ testssl.sh +COPY --chown=testssl . /home/testssl/ ENTRYPOINT ["testssl.sh"] From 9fc8c337043338b2aa508e026317df3106b7fac8 Mon Sep 17 00:00:00 2001 From: Sole Date: Thu, 2 Feb 2023 00:42:15 +0000 Subject: [PATCH 06/94] Change exception for removed root certificates into easy edit multi-value regular expression for Organization name and making it clear that CA's are actively removed from 1+ root stores. --- testssl.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index 77d7bd6..1bbc7c0 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9416,10 +9416,11 @@ certificate_info() { out "$indent"; pr_bold " Chain of trust"; out " " jsonID="cert_chain_of_trust" - if [[ "$issuer_O" =~ StartCom ]] || [[ "$issuer_O" =~ WoSign ]] || [[ "$issuer_CN" =~ StartCom ]] || [[ "$issuer_CN" =~ WoSign ]]; then - # Shortcut for this special case here. - pr_italic "WoSign/StartCom"; out " are " ; prln_svrty_critical "not trusted anymore (NOT ok)" - fileout "${jsonID}${json_postfix}" "CRITICAL" "Issuer not trusted anymore (WoSign/StartCom)" + # Looks for CA's that have their trust removed by the first part of their Organization Name as they can only used verified names + if [[ "$issuer_O" =~ ^(TrustCor Systems|WoSign|StartCom) ]]; then + # Shortcut for this special case here. There is a difference between not being in a root store and being removed from a root store. + pr_italic "$issuer_O"; out " is " ; prln_svrty_critical "actively removed from one or more root stores (NOT ok)" + fileout "${jsonID}${json_postfix}" "CRITICAL" "Issuer removed from one or more root stores ($issuer_O)" set_grade_cap "T" "Untrusted certificate chain" else # Also handles fileout, keep error if happened From dc7d13b8530716689d49d39ca52390b4ee7effb4 Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:06:29 +1300 Subject: [PATCH 07/94] chore(Dockerfile): Simplify `testssl` user creation Create `testssl` user (_and group_) with no password (`-D`) and default their shell to bash (`-s`): - A group will implicitly be created with the same value as the user. `addgroup testssl` and `-G testssl` are not needed. - Gecos data (`-g "testssl user"`) doesn't appear relevant to the project to be required? The default gecos value (`Linux User,,,`) should be fine. --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2ccf505..53e8bd2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,8 +4,7 @@ RUN apk update && \ apk upgrade && \ apk add bash procps drill git coreutils libidn curl socat openssl xxd && \ rm -rf /var/cache/apk/* && \ - addgroup testssl && \ - adduser -G testssl -g "testssl user" -s /bin/bash -D testssl && \ + adduser -D -s /bin/bash testssl && \ ln -s /home/testssl/testssl.sh /usr/local/bin/ && \ mkdir -m 755 -p /home/testssl/etc /home/testssl/bin From 3670c1e4ad8479e32e44d6e76c9ff6039e643b4d Mon Sep 17 00:00:00 2001 From: Sole Date: Thu, 2 Feb 2023 01:13:00 +0000 Subject: [PATCH 08/94] Removed non-relevant CA's that no longer have active certificates. --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1bbc7c0..16374ae 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9416,8 +9416,8 @@ certificate_info() { out "$indent"; pr_bold " Chain of trust"; out " " jsonID="cert_chain_of_trust" - # Looks for CA's that have their trust removed by the first part of their Organization Name as they can only used verified names - if [[ "$issuer_O" =~ ^(TrustCor Systems|WoSign|StartCom) ]]; then + # Looks for CA's that have their trust removed by the first part of their Organization Name, add multiple with ^(TrustCor Systems|WoSign) etc. + if [[ "$issuer_O" =~ ^(TrustCor Systems) ]]; then # Shortcut for this special case here. There is a difference between not being in a root store and being removed from a root store. pr_italic "$issuer_O"; out " is " ; prln_svrty_critical "actively removed from one or more root stores (NOT ok)" fileout "${jsonID}${json_postfix}" "CRITICAL" "Issuer removed from one or more root stores ($issuer_O)" From 76b8f0c981805f840f8b2832adebadcc8791e068 Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Thu, 2 Feb 2023 14:26:16 +1300 Subject: [PATCH 09/94] chore: Remove redundant `mkdir` - If local folder ownership is for example `644` it will fail to handle the `COPY` regardless (while `744` would work). - Creating the directory with higher permissions in the container does not appear to help. --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2ccf505..34fa45a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,8 +6,7 @@ RUN apk update && \ rm -rf /var/cache/apk/* && \ addgroup testssl && \ adduser -G testssl -g "testssl user" -s /bin/bash -D testssl && \ - ln -s /home/testssl/testssl.sh /usr/local/bin/ && \ - mkdir -m 755 -p /home/testssl/etc /home/testssl/bin + ln -s /home/testssl/testssl.sh /usr/local/bin/ USER testssl WORKDIR /home/testssl/ From b661f7b8d348872203f09084eef59d43681d2284 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 2 Feb 2023 16:56:42 -0800 Subject: [PATCH 10/94] Update documentation for cipherlists tests The sets of cipher lists checked by `run_cipherslists()` changed in 3.1dev, but the documentation was not updated. --- doc/testssl.1 | 10 ++++++---- doc/testssl.1.html | 10 ++++++---- doc/testssl.1.md | 9 +++++---- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/doc/testssl.1 b/doc/testssl.1 index c34ece8..030774a 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -128,13 +128,15 @@ Any single check switch supplied as an argument prevents testssl\.sh from doing .IP "\[ci]" 4 \fBExport ciphers\fR (w/o the preceding ones): 'EXPORT:!ADH:!NULL' .IP "\[ci]" 4 -\fBLOW\fR (64 Bit + DES ciphers, without EXPORT ciphers): 'LOW:DES:RC2:RC4:!ADH:!EXP:!NULL:!eNULL' +\fBLOW\fR (64 Bit + DES ciphers, without EXPORT ciphers): 'LOW:DES:RC2:RC4:MD5:!ADH:!EXP:!NULL:!eNULL:!AECDH' .IP "\[ci]" 4 -\fB3DES + IDEA Ciphers\fR: '3DES:IDEA:!aNULL:!ADH' +\fB3DES + IDEA ciphers\fR: '3DES:IDEA:!aNULL:!ADH:!MD5' .IP "\[ci]" 4 -\fBAverage grade Ciphers\fR: 'HIGH:MEDIUM:AES:CAMELLIA:ARIA:!IDEA:!CHACHA20:!3DES:!RC2:!RC4:!AESCCM8:!AESCCM:!AESGCM:!ARIAGCM:!aNULL' +\fBObsoleted CBC ciphers\fR: 'HIGH:MEDIUM:AES:CAMELLIA:ARIA:!IDEA:!CHACHA20:!3DES:!RC2:!RC4:!AESCCM8:!AESCCM:!AESGCM:!ARIAGCM:!aNULL:!MD5' .IP "\[ci]" 4 -\fBStrong grade Ciphers\fR (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM8:AESCCM' +\fBStrong ciphers with no FS\fR (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kEECDH:!kEDH:!kDHE:!kDHEPSK:!kECDHEPSK:!aNULL' +.IP "\[ci]" 4 +\fBForward Secrecy strong ciphers\fR (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kPSK:!kRSAPSK:!kRSA:!kDH:!kECDH:!aNULL' .IP "" 0 .P \fB\-f, \-\-fs, \-\-nsa, \-\-forward\-secrecy\fR Checks robust forward secrecy key exchange\. "Robust" means that ciphers having intrinsic severe weaknesses like Null Authentication or Encryption, 3DES and RC4 won't be considered here\. There shouldn't be the wrong impression that a secure key exchange has been taking place and everything is fine when in reality the encryption sucks\. Also this section lists the available elliptical curves and Diffie Hellman groups, as well as FFDHE groups (TLS 1\.2 and TLS 1\.3)\. diff --git a/doc/testssl.1.html b/doc/testssl.1.html index 9b43ca6..21d35db 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -247,13 +247,15 @@ in /etc/hosts. The use of the switch is only useful if you either
  • Export ciphers (w/o the preceding ones): 'EXPORT:!ADH:!NULL'
  • -LOW (64 Bit + DES ciphers, without EXPORT ciphers): 'LOW:DES:RC2:RC4:!ADH:!EXP:!NULL:!eNULL'
  • +LOW (64 Bit + DES ciphers, without EXPORT ciphers): 'LOW:DES:RC2:RC4:MD5:!ADH:!EXP:!NULL:!eNULL:!AECDH'
  • -3DES + IDEA Ciphers: '3DES:IDEA:!aNULL:!ADH'
  • +3DES + IDEA ciphers: '3DES:IDEA:!aNULL:!ADH:!MD5'
  • -Average grade Ciphers: 'HIGH:MEDIUM:AES:CAMELLIA:ARIA:!IDEA:!CHACHA20:!3DES:!RC2:!RC4:!AESCCM8:!AESCCM:!AESGCM:!ARIAGCM:!aNULL'
  • +Obsoleted CBC ciphers: 'HIGH:MEDIUM:AES:CAMELLIA:ARIA:!IDEA:!CHACHA20:!3DES:!RC2:!RC4:!AESCCM8:!AESCCM:!AESGCM:!ARIAGCM:!aNULL:!MD5'
  • -Strong grade Ciphers (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM8:AESCCM'
  • +Strong ciphers with no FS (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kEECDH:!kEDH:!kDHE:!kDHEPSK:!kECDHEPSK:!aNULL' +
  • +Forward Secrecy strong ciphers (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kPSK:!kRSAPSK:!kRSA:!kDH:!kECDH:!aNULL'
  • -f, --fs, --nsa, --forward-secrecy Checks robust forward secrecy key exchange. "Robust" means that ciphers having intrinsic severe weaknesses like Null Authentication or Encryption, 3DES and RC4 won't be considered here. There shouldn't be the wrong impression that a secure key exchange has been taking place and everything is fine when in reality the encryption sucks. Also this section lists the available elliptical curves and Diffie Hellman groups, as well as FFDHE groups (TLS 1.2 and TLS 1.3).

    diff --git a/doc/testssl.1.md b/doc/testssl.1.md index 2a69f46..1795cc4 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -166,10 +166,11 @@ Any single check switch supplied as an argument prevents testssl.sh from doing a * `NULL encryption ciphers`: 'NULL:eNULL' * `Anonymous NULL ciphers`: 'aNULL:ADH' * `Export ciphers` (w/o the preceding ones): 'EXPORT:!ADH:!NULL' -* `LOW` (64 Bit + DES ciphers, without EXPORT ciphers): 'LOW:DES:RC2:RC4:!ADH:!EXP:!NULL:!eNULL' -* `3DES + IDEA Ciphers`: '3DES:IDEA:!aNULL:!ADH' -* `Average grade Ciphers`: 'HIGH:MEDIUM:AES:CAMELLIA:ARIA:!IDEA:!CHACHA20:!3DES:!RC2:!RC4:!AESCCM8:!AESCCM:!AESGCM:!ARIAGCM:!aNULL' -* `Strong grade Ciphers` (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM8:AESCCM' +* `LOW` (64 Bit + DES ciphers, without EXPORT ciphers): 'LOW:DES:RC2:RC4:MD5:!ADH:!EXP:!NULL:!eNULL:!AECDH' +* `3DES + IDEA ciphers`: '3DES:IDEA:!aNULL:!ADH:!MD5' +* `Obsoleted CBC ciphers`: 'HIGH:MEDIUM:AES:CAMELLIA:ARIA:!IDEA:!CHACHA20:!3DES:!RC2:!RC4:!AESCCM8:!AESCCM:!AESGCM:!ARIAGCM:!aNULL:!MD5' +* `Strong ciphers with no FS` (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kEECDH:!kEDH:!kDHE:!kDHEPSK:!kECDHEPSK:!aNULL' +* `Forward Secrecy strong ciphers` (AEAD): 'AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kPSK:!kRSAPSK:!kRSA:!kDH:!kECDH:!aNULL' `-f, --fs, --nsa, --forward-secrecy` Checks robust forward secrecy key exchange. "Robust" means that ciphers having intrinsic severe weaknesses like Null Authentication or Encryption, 3DES and RC4 won't be considered here. There shouldn't be the wrong impression that a secure key exchange has been taking place and everything is fine when in reality the encryption sucks. Also this section lists the available elliptical curves and Diffie Hellman groups, as well as FFDHE groups (TLS 1.2 and TLS 1.3). From 3d82f7cb211f6f2c2623b36d04ab760a7e30909e Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 3 Feb 2023 14:18:02 -0800 Subject: [PATCH 11/94] Fix HTML output in Bash 5.2 and newer As noted in #2304, the way that the '&' character is treated in the string part of a pattern substitution changed in Bash 5.2. As a result, the change that was made in #1481 to accommodate older versions of Bash (e.g., on MacOS) now causes testssl.sh to produce incorrect HTML output when run on Bash 5.2. This commit encodes the '&' characters in the substitution strings in a way that produces correct results on multiple versions of Bash (3.2 on MacOS, 5.2 on Ubuntu 23.10, 5.0 on Ubuntu 20.04). --- testssl.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 16374ae..58a1c23 100755 --- a/testssl.sh +++ b/testssl.sh @@ -535,11 +535,11 @@ html_reserved(){ local output "$do_html" || return 0 #sed -e 's/\&/\&/g' -e 's//\>/g' -e 's/"/\"/g' -e "s/'/\'/g" <<< "$1" - output="${1//&/&}" - output="${output///>}" - output="${output//\"/"}" - output="${output//\'/'}" + output="${1//&/$'&'amp;}" + output="${output///$'&'gt;}" + output="${output//\"/$'&'quot;}" + output="${output//\'/$'&'apos;}" printf -- "%s" "$output" return 0 } From 6f881dc70b7ce55c26d830e3bc8bc369ad5f10b0 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 Feb 2023 19:32:08 +0100 Subject: [PATCH 12/94] Rename 3 jsonIDs in run_cipherlists(): breaking change see #2316 / #2320 AVERAGE --> OBSOLETED GOOD --> STRONG_NOFS STRONG --> STRONG_FS --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 58a1c23..be14b90 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6254,11 +6254,11 @@ run_cipherlists() { ret=$((ret + $?)) sub_cipherlists "$ossl_tdes_ciphers" "" " Triple DES Ciphers / IDEA " 3 "3DES_IDEA" "$tdes_ciphers" "$sslv2_tdes_ciphers" "$using_sockets" "$cve" "$cwe2" ret=$((ret + $?)) - sub_cipherlists "$ossl_obsoleted_ciphers" "" " Obsoleted CBC ciphers (AES, ARIA etc.) " 4 "AVERAGE" "$obsoleted_ciphers" "" "$using_sockets" "$cve" "$cwe2" + sub_cipherlists "$ossl_obsoleted_ciphers" "" " Obsoleted CBC ciphers (AES, ARIA etc.) " 4 "OBSOLETED" "$obsoleted_ciphers" "" "$using_sockets" "$cve" "$cwe2" ret=$((ret + $?)) - sub_cipherlists "$ossl_good_ciphers" "" " Strong encryption (AEAD ciphers) with no FS " 6 "GOOD" "$good_ciphers" "" "$using_sockets" "" "" + sub_cipherlists "$ossl_good_ciphers" "" " Strong encryption (AEAD ciphers) with no FS " 6 "STRONG_NOFS" "$good_ciphers" "" "$using_sockets" "" "" ret=$((ret + $?)) - sub_cipherlists "$ossl_strong_ciphers" 'ALL' " Forward Secrecy strong encryption (AEAD ciphers)" 7 "STRONG" "$strong_ciphers" "" "$using_sockets" "" "" + sub_cipherlists "$ossl_strong_ciphers" 'ALL' " Forward Secrecy strong encryption (AEAD ciphers)" 7 "STRONG_FS" "$strong_ciphers" "" "$using_sockets" "" "" ret=$((ret + $?)) outln From 66ebfb2f585624c9c5e1d7b94e0f69dfd2d9f021 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 6 Feb 2023 21:56:54 +0100 Subject: [PATCH 13/94] Add changes to CSV baseline --- t/baseline_data/default_testssl.csvfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/t/baseline_data/default_testssl.csvfile b/t/baseline_data/default_testssl.csvfile index a265981..4a0866b 100644 --- a/t/baseline_data/default_testssl.csvfile +++ b/t/baseline_data/default_testssl.csvfile @@ -15,9 +15,9 @@ "cipherlist_EXPORT","testssl.sh/81.169.166.184","443","OK","not offered","","CWE-327" "cipherlist_LOW","testssl.sh/81.169.166.184","443","OK","not offered","","CWE-327" "cipherlist_3DES_IDEA","testssl.sh/81.169.166.184","443","INFO","not offered","","CWE-310" -"cipherlist_AVERAGE","testssl.sh/81.169.166.184","443","LOW","offered","","CWE-310" -"cipherlist_GOOD","testssl.sh/81.169.166.184","443","OK","offered","","" -"cipherlist_STRONG","testssl.sh/81.169.166.184","443","OK","offered","","" +"cipherlist_OBSOLETED","testssl.sh/81.169.166.184","443","LOW","offered","","CWE-310" +"cipherlist_STRONG_NOFS","testssl.sh/81.169.166.184","443","OK","offered","","" +"cipherlist_STRONG_FS","testssl.sh/81.169.166.184","443","OK","offered","","" "cipher_order-tls1","testssl.sh/81.169.166.184","443","OK","server","","" "cipher-tls1_xc014","testssl.sh/81.169.166.184","443","LOW","TLSv1 xc014 ECDHE-RSA-AES256-SHA ECDH 256 AES 256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","","" "cipher-tls1_xc013","testssl.sh/81.169.166.184","443","LOW","TLSv1 xc013 ECDHE-RSA-AES128-SHA ECDH 256 AES 128 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","","" From 81634ce13d42c3704301795a6392e3baac80765a Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Tue, 7 Feb 2023 21:36:47 +1300 Subject: [PATCH 14/94] chore: Bring back group value for `COPY --chown` --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 49b3553..ace017a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ USER testssl WORKDIR /home/testssl/ # Copy over build context (after filtered by .dockerignore): bin/ etc/ testssl.sh -COPY --chown=testssl . /home/testssl/ +COPY --chown=testssl:testssl . /home/testssl/ ENTRYPOINT ["testssl.sh"] From f914423978bfc0b6bddf423605417a2037eb1bf5 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Tue, 7 Feb 2023 10:28:26 +0100 Subject: [PATCH 15/94] Remove mkdir in Dockerfile see https://github.com/drwetter/testssl.sh/pull/2312#pullrequestreview-1286620850 --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 53e8bd2..1e14995 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,8 +5,7 @@ RUN apk update && \ apk add bash procps drill git coreutils libidn curl socat openssl xxd && \ rm -rf /var/cache/apk/* && \ adduser -D -s /bin/bash testssl && \ - ln -s /home/testssl/testssl.sh /usr/local/bin/ && \ - mkdir -m 755 -p /home/testssl/etc /home/testssl/bin + ln -s /home/testssl/testssl.sh /usr/local/bin/ USER testssl WORKDIR /home/testssl/ From a14fc5bdcfc6a53f67e9e09dd17babd5a8e3ff85 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 20 Feb 2023 15:01:40 +0100 Subject: [PATCH 16/94] Fix Accept header see #2325. "whenever HTTP/1.1 is used then the Accept header uses "text/*" as a MIME type. This causes some minor issues with some of the checks we are doing" --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index be14b90..2c90d8e 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17193,7 +17193,7 @@ run_breach() { # Assemble the GET command with all available compressions and send them all, initially. # If the result is negative: we can just tell the finding and return. If it's # positive: We already have identified 1x compression - get_command="GET $url HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $useragent\r\nReferer: $referer\r\nConnection: Close\r\nAccept-encoding: ${compressions// /,}\r\nAccept: text/*\r\n\r\n" + get_command="GET $url HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $useragent\r\nReferer: $referer\r\nConnection: Close\r\nAccept-encoding: ${compressions// /,}\r\nAccept: */*\r\n\r\n" detected_compression=$(sub_breach_helper "$get_command") case "$detected_compression" in warn_stalled) @@ -17216,7 +17216,7 @@ run_breach() { has_compression+=("$detected_compression:yes") compressions="${compressions//$detected_compression/}" for c in $compressions; do - get_command="GET $url HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $useragent\r\nReferer: $referer\r\nConnection: Close\r\nAccept-encoding: ${c}\r\nAccept: text/*\r\n\r\n" + get_command="GET $url HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $useragent\r\nReferer: $referer\r\nConnection: Close\r\nAccept-encoding: ${c}\r\nAccept: */*\r\n\r\n" detected_compression=$(sub_breach_helper "$get_command") if [[ $? -ne 0 ]]; then # This failure unlikely here. The initial request must have succeeded and this one then @@ -21854,7 +21854,7 @@ determine_service() { if [[ -n "$REQHEADERS" ]]; then reqheader="$(join_by "\r\n" "${REQHEADERS[@]}")\r\n" #Add all required custom http headers to one string with newlines fi - GET_REQ11="GET $URL_PATH HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $ua\r\n${basicauth_header}${reqheader}Accept-Encoding: identity\r\nAccept: text/*\r\nConnection: Close\r\n\r\n" + GET_REQ11="GET $URL_PATH HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $ua\r\n${basicauth_header}${reqheader}Accept-Encoding: identity\r\nAccept: */*\r\nConnection: Close\r\n\r\n" determine_optimal_proto # returns always 0: service_detection $OPTIMAL_PROTO From 2b6bd2f1dd0a83ea0ed7d4b9ccfb363fa7fc4138 Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 3 Mar 2023 12:47:12 +0100 Subject: [PATCH 17/94] fix indentation --- testssl.sh | 64 +++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/testssl.sh b/testssl.sh index d8d9b63..845f40f 100755 --- a/testssl.sh +++ b/testssl.sh @@ -196,7 +196,7 @@ TESTSSL_INSTALL_DIR="${TESTSSL_INSTALL_DIR:-""}" # If you run testssl.sh and it CA_BUNDLES_PATH="${CA_BUNDLES_PATH:-""}" # You can have your CA stores some place else EXPERIMENTAL=${EXPERIMENTAL:-false} # a development hook which allows us to disable code PROXY_WAIT=${PROXY_WAIT:-20} # waiting at max 20 seconds for socket reply through proxy -DNS_VIA_PROXY=${DNS_VIA_PROXY:-false} # do DNS lookups via proxy. --ip=proxy reverses this +DNS_VIA_PROXY=${DNS_VIA_PROXY:-false} # do DNS lookups via proxy. --ip=proxy reverses this IGN_OCSP_PROXY=${IGN_OCSP_PROXY:-false} # Also when --proxy is supplied it is ignored when testing for revocation via OCSP via --phone-out HEADER_MAXSLEEP=${HEADER_MAXSLEEP:-5} # we wait this long before killing the process to retrieve a service banner / http header MAX_SOCKET_FAIL=${MAX_SOCKET_FAIL:-2} # If this many failures for TCP socket connects are reached we terminate @@ -19986,7 +19986,7 @@ find_openssl_binary() { HAS_ZLIB=false HAS_UDS=false HAS_UDS2=false - TRUSTED1ST="" + TRUSTED1ST="" HAS_ENABLE_PHA=false $OPENSSL ciphers -s 2>&1 | grep -aiq "unknown option" || OSSL_CIPHERS_S="-s" @@ -22041,18 +22041,18 @@ display_rdns_etc() { datebanner() { local scan_time_f="" local node_banner="" - + if [[ -n "PROXY" ]] && $DNS_VIA_PROXY;then - node_banner="$NODE:$PORT" + node_banner="$NODE:$PORT" else - node_banner="$NODEIP:$PORT ($NODE)" + node_banner="$NODEIP:$PORT ($NODE)" fi - + if [[ "$1" =~ Done ]] ; then scan_time_f="$(printf "%04ss" "$SCAN_TIME")" # 4 digits because of windows pr_reverse "$1 $(date +%F) $(date +%T) [$scan_time_f] -->> $node_banner <<--" else - pr_reverse "$1 $(date +%F) $(date +%T) -->> $node_banner <<--" + pr_reverse "$1 $(date +%F) $(date +%T) -->> $node_banner <<--" fi outln "\n" [[ "$1" =~ Start ]] && display_rdns_etc @@ -23970,30 +23970,30 @@ lets_roll() { [[ -z "$NODE" ]] && parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDRs and IP46ADDR is set now prepare_logging - if [[ -n "$PROXY" ]] && $DNS_VIA_PROXY; then - NODEIP="$NODE" - lets_roll "${STARTTLS_PROTOCOL}" - RET=$? - else - determine_ip_addresses - if [[ $(count_words "$IPADDRs") -gt 1 ]]; then # we have more than one ipv4 address to check - MULTIPLE_CHECKS=true - pr_bold "Testing all IPv4 addresses (port $PORT): "; outln "$IPADDRs" - for ip in $IPADDRs; do - draw_line "-" $((TERM_WIDTH * 2 / 3)) - outln - NODEIP="$ip" - lets_roll "${STARTTLS_PROTOCOL}" - RET=$((RET + $?)) # RET value per IP address - done - draw_line "-" $((TERM_WIDTH * 2 / 3)) - outln - pr_bold "Done testing now all IP addresses (on port $PORT): "; outln "$IPADDRs" - else # Just 1x ip4v to check, applies also if CMDLINE_IP was supplied - NODEIP="$IPADDRs" - lets_roll "${STARTTLS_PROTOCOL}" - RET=$? - fi - fi + if [[ -n "$PROXY" ]] && $DNS_VIA_PROXY; then + NODEIP="$NODE" + lets_roll "${STARTTLS_PROTOCOL}" + RET=$? + else + determine_ip_addresses + if [[ $(count_words "$IPADDRs") -gt 1 ]]; then # we have more than one ipv4 address to check + MULTIPLE_CHECKS=true + pr_bold "Testing all IPv4 addresses (port $PORT): "; outln "$IPADDRs" + for ip in $IPADDRs; do + draw_line "-" $((TERM_WIDTH * 2 / 3)) + outln + NODEIP="$ip" + lets_roll "${STARTTLS_PROTOCOL}" + RET=$((RET + $?)) # RET value per IP address + done + draw_line "-" $((TERM_WIDTH * 2 / 3)) + outln + pr_bold "Done testing now all IP addresses (on port $PORT): "; outln "$IPADDRs" + else # Just 1x ip4v to check, applies also if CMDLINE_IP was supplied + NODEIP="$IPADDRs" + lets_roll "${STARTTLS_PROTOCOL}" + RET=$? + fi + fi exit $RET From 9afa277c02d36cc7223e766c5bf909bdb61e76d3 Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 3 Mar 2023 12:50:02 +0100 Subject: [PATCH 18/94] another indent correction --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 845f40f..a432bdb 100755 --- a/testssl.sh +++ b/testssl.sh @@ -19986,7 +19986,7 @@ find_openssl_binary() { HAS_ZLIB=false HAS_UDS=false HAS_UDS2=false - TRUSTED1ST="" + TRUSTED1ST="" HAS_ENABLE_PHA=false $OPENSSL ciphers -s 2>&1 | grep -aiq "unknown option" || OSSL_CIPHERS_S="-s" From 06506b371ef7bfb5aabe8fa39d50111d1f10c232 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sat, 11 Mar 2023 13:38:28 +0100 Subject: [PATCH 19/94] Make sure control chars from HTTP header don't end up in html,csv,json This addresses the bug #2330 by implementing a function which removes control characters from the file output format html,csv,json at the output. In every instance called there's a check before whether the string contains control chars, hoping it'll save a few milli seconds. A tr function is used, omitting LF. It doesn't filter the terminal output and the log file output. --- testssl.sh | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 58a1c23..955a4fe 100755 --- a/testssl.sh +++ b/testssl.sh @@ -534,7 +534,6 @@ show_finding() { html_reserved(){ local output "$do_html" || return 0 - #sed -e 's/\&/\&/g' -e 's//\>/g' -e 's/"/\"/g' -e "s/'/\'/g" <<< "$1" output="${1//&/$'&'amp;}" output="${output///$'&'gt;}" @@ -545,8 +544,26 @@ html_reserved(){ } html_out() { + local outstr="$1" + "$do_html" || return 0 - [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] && printf -- "%b" "$1" >> "$HTMLFILE" + if [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]]; then + if [[ "$outstr" =~ [[:cntrl:]] ]]; then + outstr="$(sanitize_fileout "$outstr")" + fi + printf -- "%b" "$outstr" >> "$HTMLFILE" + fi +} + +# Removes on printable chars in CSV, JSON, HTML, see #2330 +sanitize_fileout() { + tr -d '\000-\011,\013-\037' <<< "$1" +} + +# Removes on printable chars in terminal output (log files) +# We need to keep the icolor ANSI escape code, see #2330 +sanitize_termout() { + tr -d '\000-\011,\013-\032,\034-\037' <<< "$1" } # This is intentionally the same. @@ -1227,6 +1244,9 @@ fileout_json_print_parameter() { spaces=" " || \ spaces=" " if [[ -n "$value" ]] || [[ "$parameter" == finding ]]; then + if [[ "$value" =~ [[:cntrl:]] ]]; then + value="$(sanitize_fileout "$value")" + fi printf -- "%b%b%b%b" "$spaces" "\"$parameter\"" "$filler" ": \"$value\"" >> "$JSONFILE" "$not_last" && printf ",\n" >> "$JSONFILE" fi @@ -1350,12 +1370,19 @@ fileout_insert_warning() { fi } +# args: "id" "fqdn/ip" "port" "severity" "finding" "cve" "cwe" "hint" +# fileout_csv_finding() { + local finding="$5" + + if [[ "$finding" =~ [[:cntrl:]] ]]; then + finding="$(sanitize_fileout "$finding")" + fi safe_echo "\"$1\"," >> "$CSVFILE" safe_echo "\"$2\"," >> "$CSVFILE" safe_echo "\"$3\"," >> "$CSVFILE" safe_echo "\"$4\"," >> "$CSVFILE" - safe_echo "\"$5\"," >> "$CSVFILE" + safe_echo "\"$finding\"," >> "$CSVFILE" safe_echo "\"$6\"," >> "$CSVFILE" if "$GIVE_HINTS"; then safe_echo "\"$7\"," >> "$CSVFILE" From d298b41d2cdd153473c6467c9f4be4199ea9c2b5 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sat, 11 Mar 2023 14:06:47 +0100 Subject: [PATCH 20/94] add aNULL exception to codespell --- .github/workflows/codespell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 1c33479..3165b94 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -13,4 +13,4 @@ jobs: - uses: codespell-project/actions-codespell@master with: skip: ca_hashes.txt,tls_data.txt,*.pem,OPENSSL-LICENSE.txt - ignore_words_list: borken,gost,ciph,ba,bloc,isnt,chello,fo,alle + ignore_words_list: borken,gost,ciph,ba,bloc,isnt,chello,fo,alle,aNULL From fab67d0cca37b7f3f6f3819e6f117d3266553f8f Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 12 Mar 2023 14:00:55 +0100 Subject: [PATCH 21/94] Remove CR in server banner ... which caused a problem in t/32_isHTML_valid.t. Also the test for an empty server banner was simplified --- testssl.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 955a4fe..8d1bd71 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3129,16 +3129,18 @@ run_server_banner() { grep -ai '^Server' $HEADERFILE >$TMPFILE if [[ $? -eq 0 ]]; then serverbanner=$(sed -e 's/^Server: //' -e 's/^server: //' $TMPFILE) - if [[ "$serverbanner" == $'\n' ]] || [[ "$serverbanner" == $'\r' ]] || [[ "$serverbanner" == $'\n\r' ]] || [[ -z "$serverbanner" ]]; then + serverbanner=${serverbanner//$'\r'} + serverbanner=${serverbanner//$'\n'} + if [[ -z "$serverbanner" ]]; then outln "exists but empty string" fileout "$jsonID" "INFO" "Server banner is empty" else emphasize_stuff_in_headers "$serverbanner" fileout "$jsonID" "INFO" "$serverbanner" if [[ "$serverbanner" == *Microsoft-IIS/6.* ]] && [[ $OSSL_VER == 1.0.2* ]]; then - prln_warning " It's recommended to run another test w/ OpenSSL 1.0.1 !" + prln_warning " It's recommended to run another test w/ OpenSSL >= 1.0.1 !" # see https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892 - fileout "${jsonID}" "WARN" "IIS6_openssl_mismatch: Recommended to rerun this test w/ OpenSSL 1.0.1. See https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892" + fileout "${jsonID}" "WARN" "IIS6_openssl_mismatch: Recommended to rerun this test w/ OpenSSL >= 1.0.1. See https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892" fi fi # mozilla.github.io/server-side-tls/ssl-config-generator/ From 2e33c483dd2fa1dbbe4e6dfd5ea53710b092bae7 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 12 Mar 2023 14:52:11 +0100 Subject: [PATCH 22/94] remove comma in tr as it was interpreted as such --- testssl.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 8d1bd71..5d4b98c 100755 --- a/testssl.sh +++ b/testssl.sh @@ -555,15 +555,15 @@ html_out() { fi } -# Removes on printable chars in CSV, JSON, HTML, see #2330 +# Removes non-printable chars in CSV, JSON, HTML, see #2330 sanitize_fileout() { - tr -d '\000-\011,\013-\037' <<< "$1" + tr -d '\000-\011\013-\037' <<< "$1" } -# Removes on printable chars in terminal output (log files) -# We need to keep the icolor ANSI escape code, see #2330 +# Removes non-printable chars in terminal output (log files) +# We need to keep the color ANSI escape code x1b, o33, see #2330 sanitize_termout() { - tr -d '\000-\011,\013-\032,\034-\037' <<< "$1" + tr -d '\000-\011\013-\032\034-\037' <<< "$1" } # This is intentionally the same. From cacd8c57b10c455c76960692e98b293c037f90af Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 12 Mar 2023 15:09:24 +0100 Subject: [PATCH 23/94] Add variable htmlfile + filter GOST message ... which is needed for newer LibreSSL/OpenSSL versions --- t/32_isHTML_valid.t | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/t/32_isHTML_valid.t b/t/32_isHTML_valid.t index becef33..0524372 100755 --- a/t/32_isHTML_valid.t +++ b/t/32_isHTML_valid.t @@ -15,22 +15,23 @@ my $out=""; my $html=""; my $debughtml=""; my $edited_html=""; -my $check2run="--ip=one --ids-friendly --color 0 --htmlfile tmp.html"; +my $htmlfile="tmp.html"; +my $check2run="--ip=one --ids-friendly --color 0 --htmlfile $htmlfile"; my $diff=""; die "Unable to open $prg" unless -f $prg; printf "\n%s\n", "Doing HTML output checks"; -unlink 'tmp.html'; +unlink $htmlfile; #1 printf "%s\n", " .. running $prg against \"$uri\" to create HTML and terminal outputs (may take ~2 minutes)"; # specify a TERM_WIDTH so that the two calls to testssl.sh don't create HTML files with different values of TERM_WIDTH $out = `TERM_WIDTH=120 $prg $check2run $uri`; -$html = `cat tmp.html`; +$html = `cat $htmlfile`; # $edited_html will contain the HTML with formatting information removed in order to compare against terminal output # Start by removing the HTML header. -$edited_html = `tail -n +11 tmp.html`; -unlink 'tmp.html'; +$edited_html = `tail -n +11 $htmlfile`; +unlink $htmlfile; # Remove the HTML footer $edited_html =~ s/\n\<\/pre\>\n\<\/body\>\n\<\/html\>//; @@ -51,12 +52,13 @@ $tests++; $diff = diff \$edited_html, \$out; printf "\n%s\n", "$diff"; + #2 printf "\n%s\n", " .. running again $prg against \"$uri\", now with --debug 4 to create HTML output (may take another ~2 minutes)"; # Redirect stderr to /dev/null in order to avoid some unexplained "date: invalid date" error messages $out = `TERM_WIDTH=120 $prg $check2run --debug 4 $uri 2> /dev/null`; -$debughtml = `cat tmp.html`; -unlink 'tmp.html'; +$debughtml = `cat $htmlfile`; +unlink $htmlfile; # Remove date information from the Start and Done banners in the two HTML files, since they were created at different times $html =~ s/Start 2[0-9][0-9][0-9]-[0-3][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]/Start XXXX-XX-XX XX:XX:XX/; @@ -72,6 +74,7 @@ $debughtml =~ s/HTTP clock skew \+?-?[0-9]* /HTTP clock skew $debughtml =~ s/ Pre-test: .*\n//g; $debughtml =~ s/.*OK: below 825 days.*\n//g; $debughtml =~ s/.*DEBUG:.*\n//g; +$debughtml =~ s/No engine or GOST support via engine with your.*\n//g; cmp_ok($debughtml, "eq", $html, "HTML file created with --debug 4 matches HTML file created without --debug"); $tests++; From 8643ed4c72cc497d09d47053177a998474c49362 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 12 Mar 2023 15:57:01 +0100 Subject: [PATCH 24/94] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4ba38ea..6d0ba2b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ tmp.html *.log *.xml *.iml +*.script *.swp *.swo *~ From 6cea273a68228c07311111e1c4817ae4e063acad Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 12 Mar 2023 17:55:10 +0100 Subject: [PATCH 25/94] Update codespell.yml add exception for aNULL which should work now --- .github/workflows/codespell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 3165b94..946363f 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -13,4 +13,4 @@ jobs: - uses: codespell-project/actions-codespell@master with: skip: ca_hashes.txt,tls_data.txt,*.pem,OPENSSL-LICENSE.txt - ignore_words_list: borken,gost,ciph,ba,bloc,isnt,chello,fo,alle,aNULL + ignore_words_list: borken,gost,ciph,ba,bloc,isnt,chello,fo,alle,anull From 419aae3c98f2317cf0e36ab19839085e37b8e32c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 17 Mar 2023 18:05:24 +0100 Subject: [PATCH 26/94] updates docu to reflekt actual status --- etc/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/README.md b/etc/README.md index b4a49db..49b4f5b 100644 --- a/etc/README.md +++ b/etc/README.md @@ -5,8 +5,8 @@ The certificate trust stores were retrieved from * **Linux:** Copied from an up-to-date Debian Linux machine * **Mozilla:** https://curl.haxx.se/docs/caextract.html -* **Java:** extracted (``keytool -list -rfc -keystore lib/security/cacerts | grep -E -v '^$|^\*\*\*\*\*|^Entry |^Creation |^Alias '``) from a JDK LTS version from https://jdk.java.net/. (use dos2unix). -* **Microsoft:** Following command pulls all certificates from Windows Update services: ``CertUtil -syncWithWU -f -f . `` (see also http://aka.ms/RootCertDownload, https://technet.microsoft.com/en-us/library/dn265983(v=ws.11).aspx#BKMK_CertUtilOptions). They are in DER format. Convert them like ``for f in *.cer; do echo $f >/dev/stderr; openssl x509 -in $f -inform DER -outform PEM ;done >/tmp/Microsoft.pem`` +* **Java:** extracted (``keytool -list -rfc -keystore lib/security/cacerts | grep -E -v '^$|^\*\*\*\*\*|^Entry |^Creation |^Alias '``) from a JDK LTS version from https://jdk.java.net/. Use dos2unix for the store which you generated. +* **Microsoft:** Following command pulls all certificates from Windows Update services: ``CertUtil -syncWithWU -f -f . `` (see also http://aka.ms/RootCertDownload, https://technet.microsoft.com/en-us/library/dn265983(v=ws.11).aspx#BKMK_CertUtilOptions). They are in DER format. Convert them like ``for f in *.crt; do echo $f >/dev/stderr; openssl x509 -in $f -inform DER -outform PEM ;done >/tmp/Microsoft.pem`` * **Apple:** 1. __System:__ from Apple OS X keychain app. Open Keychain Access utility, i.e. In the Finder window, under Favorites --> "Applications" --> "Utilities" @@ -16,7 +16,7 @@ The certificate trust stores were retrieved from Select all CA certificates except for "Developer ID Certification Authority", omit expired ones, "File" --> "Export Items" 2. __Internet:__ Pick the latest subdir (=highest number) from https://opensource.apple.com/source/security_certificates/. They are in all DER format despite their file extension. Download them with ``wget --level=1 --cut-dirs=5 --mirror --convert-links --adjust-extension --page-requisites --no-parent https://opensource.apple.com/source/security_certificates/security_certificates-/certificates/roots/``. Then: ``for f in *.cer *.der *.crt; do echo $f >/dev/stderr; openssl x509 -in $f -inform DER -outform PEM ;done >/tmp/Apple.pem`` -**Attention**: You need to remove the DST Root CA X3 which is for your reference in this directory. +**ATTENTION**: From each store you need to remove the _DST Root CA X3_ which is for your reference in this directory. See file ``DST Root CA X3.txt`` in this directory. Apple's file name is ``IdenTrust_Root_X3.der``. For the Microsoft store you have to identify the file beforehand like `` for f in *.crt; do echo $f >/dev/stderr; openssl x509 -in $f -inform DER -text -noout | grep DST ;done`` Google Chromium uses basically the trust stores above, see https://www.chromium.org/Home/chromium-security/root-ca-policy. @@ -36,7 +36,7 @@ If you want to check trust against e.g. a company internal CA you need to use `` * ``common-primes.txt`` is used for LOGJAM and the PFS section -* ``client-simulation.txt`` / ``client-simulation.wiresharked.txt`` are as the names indicate data for the client simulation. +* ``client-simulation.txt`` / ``client-simulation.wiresharked.txt`` are -- as the names indicate -- data for the client simulation. The first one is derived from ``~/utils/update_client_sim_data.pl``, and manually edited to sort and label those we don't want. The second file provides more client data retrieved from wireshark captures and some instructions how to do that yourself. From 6106887fdd980d37cffce8f3bd210c55cd6d29a4 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 17 Mar 2023 18:06:03 +0100 Subject: [PATCH 27/94] Update DST CA --- etc/DST Root CA X3.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/etc/DST Root CA X3.txt b/etc/DST Root CA X3.txt index 38751db..b2e43c9 100644 --- a/etc/DST Root CA X3.txt +++ b/etc/DST Root CA X3.txt @@ -1,5 +1,3 @@ -DST Root CA X3 - -----BEGIN CERTIFICATE----- MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT @@ -19,4 +17,4 @@ AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ ------END CERTIFICATE---- +-----END CERTIFICATE----- From aac696b0a01e9fbdfa024f93bdbd96d6f5ce5c56 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 17 Mar 2023 18:06:57 +0100 Subject: [PATCH 28/94] Updated root CA stores --- etc/Apple.pem | 3049 +++++++++++++++++++++--------------------- etc/Java.pem | 273 +--- etc/Linux.pem | 3203 +++++++++++++++++++++++---------------------- etc/Microsoft.pem | 311 ++++- etc/Mozilla.pem | 345 ++--- 5 files changed, 3571 insertions(+), 3610 deletions(-) diff --git a/etc/Apple.pem b/etc/Apple.pem index 0572dcd..90d6830 100644 --- a/etc/Apple.pem +++ b/etc/Apple.pem @@ -1,1513 +1,4 @@ -----BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ -WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ -BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG -Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ -yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf -BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz -WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF -tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z -374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC -IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL -mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 -wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS -MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 -ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet -UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H -YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 -LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 -RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM -LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf -77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N -JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm -fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp -6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp -1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B -9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok -RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv -uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP -Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr -ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL -MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 -yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr -VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ -nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG -XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj -vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt -Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g -N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC -nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz -dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL -MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp -cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y -YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua -kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL -QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp -6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG -yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i -QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ -KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO -tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu -QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ -Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u -olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 -x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz -dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG -A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U -cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf -qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ -JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ -+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS -s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 -HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 -70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG -V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S -qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S -5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia -C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX -OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE -FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 -KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B -8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ -MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc -0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ -u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF -u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH -YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 -GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO -RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e -KeC2uAloGRwYQw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFujCCBKKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMCVVMx -HTAbBgNVBAoTFEFwcGxlIENvbXB1dGVyLCBJbmMuMS0wKwYDVQQLEyRBcHBsZSBD -b21wdXRlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIEFwcGxlIFJv -b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA1MDIxMDAwMTgxNFoXDTI1MDIx -MDAwMTgxNFowgYYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBcHBsZSBDb21wdXRl -ciwgSW5jLjEtMCsGA1UECxMkQXBwbGUgQ29tcHV0ZXIgQ2VydGlmaWNhdGUgQXV0 -aG9yaXR5MSkwJwYDVQQDEyBBcHBsZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 -eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1e -eYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsq -wx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsV -WR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO -2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+ -H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeU -yS0CAwEAAaOCAi8wggIrMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ -MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlH -lHYJ/vRrjS5ApvdHTX8IXjCCASkGA1UdIASCASAwggEcMIIBGAYJKoZIhvdjZAUB -MIIBCTBBBggrBgEFBQcCARY1aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj -YXRlYXV0aG9yaXR5L3Rlcm1zLmh0bWwwgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFu -Y2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2Nl -cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5k -IGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRp -ZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wRAYDVR0fBD0wOzA5oDegNYYz -aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L3Jvb3Qu -Y3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0cHM6Ly93d3cuYXBw -bGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L2Nhc2lnbmVycy5odG1sMA0GCSqG -SIb3DQEBBQUAA4IBAQCd2i0oWC99dgS5BNM+zrdmY06PL9T+S61yvaM5xlJNBZhS -9YlRASR5vhoy9+VEi0tEBzmC1lrKtCBe2a4VXR2MHTK/ODFiSF3H4ZCx+CRA+F9Y -m1FdV53B5f88zHIhbsTp6aF31ywXJsM/65roCwO66bNKcuszCVut5mIxauivL9Wv -Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961 -kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH -CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET -MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk -BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4 -Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl -cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0 -aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY -F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N -8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe -rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K -/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu -7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC -28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6 -lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E -nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB -0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09 -5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj -WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN -jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ -KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s -ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM -OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q -619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn -2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj -o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v -nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG -5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq -pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb -dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 -BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe -Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw -IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL -SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH -SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh -ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X -DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 -TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ -fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA -sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU -WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS -nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH -dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip -NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC -AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF -MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB -uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl -PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP -JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ -gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 -j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 -5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB -o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS -/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z -Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE -W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D -hNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1 -MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB -IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK -Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg -MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH -xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ -FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q -VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH -jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l -Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED -o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI -FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF -BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW -Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX -cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz -Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4 -CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId -kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0 -MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG -EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT -CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK -8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2 -98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb -2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC -ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi -Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB -o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl -ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD -AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL -AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd -foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M -cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq -8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp -hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk -Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U -AGegcQCCSA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGATCCA+mgAwIBAgIRAI9hcRW6eVgXjH0ROqzW264wDQYJKoZIhvcNAQELBQAw -RTEfMB0GA1UEAxMWQ29tU2lnbiBHbG9iYWwgUm9vdCBDQTEVMBMGA1UEChMMQ29t -U2lnbiBMdGQuMQswCQYDVQQGEwJJTDAeFw0xMTA3MTgxMDI0NTRaFw0zNjA3MTYx -MDI0NTVaMEUxHzAdBgNVBAMTFkNvbVNpZ24gR2xvYmFsIFJvb3QgQ0ExFTATBgNV -BAoTDENvbVNpZ24gTHRkLjELMAkGA1UEBhMCSUwwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQCyKClzKh3rm6n1nvigmV/VU1D4hSwYW2ro3VqpzpPo0Ph3 -3LguqjXd5juDwN4mpxTpD99d7Xu5X6KGTlMVtfN+bTbA4t3x7DU0Zqn0BE5XuOgs -3GLH41Vmr5wox1bShVpM+IsjcN4E/hMnDtt/Bkb5s33xCG+ohz5dlq0gA9qfr/g4 -O9lkHZXTCeYrmVzd/il4x79CqNvGkdL3um+OKYl8rg1dPtD8UsytMaDgBAopKR+W -igc16QJzCbvcinlETlrzP/Ny76BWPnAQgaYBULax/Q5thVU+N3sEOKp6uviTdD+X -O6i96gARU4H0xxPFI75PK/YdHrHjfjQevXl4J37FJfPMSHAbgPBhHC+qn/014DOx -46fEGXcdw2BFeIIIwbj2GH70VyJWmuk/xLMCHHpJ/nIF8w25BQtkPpkwESL6esaU -b1CyB4Vgjyf16/0nRiCAKAyC/DY/Yh+rDWtXK8c6QkXD2XamrVJo43DVNFqGZzbf -5bsUXqiVDOz71AxqqK+p4ek9374xPNMJ2rB5MLPAPycwI0bUuLHhLy6nAIFHLhut -TNI+6Y/soYpi5JSaEjcY7pxI8WIkUAzr2r+6UoT0vAdyOt7nt1y8844a7szo/aKf -woziHl2O1w6ZXUC30K+ptXVaOiW79pBDcbLZ9ZdbONhS7Ea3iH4HJNwktrBJLQID -AQABo4HrMIHoMA8GA1UdEwEB/wQFMAMBAf8wgYQGA1UdHwR9MHswPKA6oDiGNmh0 -dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9jb21zaWduZ2xvYmFscm9vdGNh -LmNybDA7oDmgN4Y1aHR0cDovL2NybDEuY29tc2lnbi5jby5pbC9jcmwvY29tc2ln -bmdsb2JhbHJvb3RjYS5jcmwwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQCRZPY -DUhirGm6rgZbPvuqJpFQsTAfBgNVHSMEGDAWgBQCRZPYDUhirGm6rgZbPvuqJpFQ -sTANBgkqhkiG9w0BAQsFAAOCAgEAk1V5V9701xsfy4mfX+tP9Ln5e9h3N+QMwUfj -kr+k3e8iXOqADjTpUHeBkEee5tJq09ZLp/43F5tZ2eHdYq2ZEX7iWHCnOQet6Yw9 -SU1TahsrGDA6JJD9sdPFnNZooGsU1520e0zNB0dNWwxrWAmu4RsBxvEpWCJbvzQL -dOfyX85RWwli81OiVMBc5XvJ1mxsIIqli45oRynKtsWP7E+b0ISJ1n+XFLdQo/Nm -WA/5sDfT0F5YPzWdZymudMbXitimxC+n4oQE4mbQ4Zm718Iwg3pP9gMMcSc7Qc1J -kJHPH9O7gVubkKHuSYj9T3Ym6c6egL1pb4pz/uT7cT26Fiopc/jdqbe2EAfoJZkv -hlp/zdzOoXTWjiKNA5zmgWnZn943FuE9KMRyKtyi/ezJXCh8ypnqLIKxeFfZl69C -BwJsPXUTuqj8Fic0s3aZmmr7C4jXycP+Q8V+akMEIoHAxcd960b4wVWKqOcI/kZS -Q0cYqWOY1LNjznRt9lweWEfwDBL3FhrHOmD4++1N3FkkM4W+Q1b2WOL24clDMj+i -2n9Iw0lc1llHMSMvA5D0vpsXZpOgcCVahfXczQKi9wQ3oZyonJeWx4/rXdMtagAB -VBYGFuMEUEQtybI+eIbnp5peO2WAAblQI4eTy/jMVowe5tfMEXovV3sz9ULgmGb3 -DscLP1I= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw -PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu -MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx -GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL -MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf -HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh -gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW -v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue -Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr -9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt -6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 -MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl -Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 -ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq -hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p -iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC -dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL -kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL -hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 -MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub -j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo -U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b -u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ -bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er -fF6adulZkMV8gzURZVE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN -BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl -bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv -b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ -BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj -YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 -MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 -dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg -QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa -jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi -C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep -lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof -TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix -RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p -YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw -NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK -EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl -cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz -dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ -fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns -bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD -75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP -FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV -HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp -5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu -b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA -A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p -6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 -dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys -Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI -l7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix -DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k -IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT -N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v -dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG -A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh -ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx -QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA -4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 -AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 -4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C -ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV -9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD -gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 -Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq -NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko -LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd -ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I -XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI -M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot -9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V -Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea -j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh -X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ -l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf -bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 -pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK -e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 -vm9qp/UsQu0yrbYhnr68 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDcTCCAlmgAwIBAgIVAOYJ/nrqAGiM4CS07SAbH+9StETRMA0GCSqGSIb3DQEB -BQUAMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGlj -emVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIgUk9PVCBDQTAeFw0xMTEyMDYx -MTEwNTdaFw0zMTEyMDYxMTEwNTdaMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIg -Uk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKxHL49ZMTml -6g3wpYwrvQKkvc0Kc6oJ5sxfgmp1qZfluwbv88BdocHSiXlY8NzrVYzuWBp7J/9K -ULMAoWoTIzOQ6C9TNm4YbA9A1jdX1wYNL5Akylf8W5L/I4BXhT9KnlI6x+a7BVAm -nr/Ttl+utT/Asms2fRfEsF2vZPMxH4UFqOAhFjxTkmJWf2Cu4nvRQJHcttB+cEAo -ag/hERt/+tzo4URz6x6r19toYmxx4FjjBkUhWQw1X21re//Hof2+0YgiwYT84zLb -eqDqCOMOXxvH480yGDkh/QoazWX3U75HQExT/iJlwnu7I1V6HXztKIwCBjsxffbH -3jOshCJtywcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFFOSo33/gnbwM9TrkmdHYTMbaDsqMA0GCSqGSIb3DQEBBQUA -A4IBAQA5UFWd5EL/pBviIMm1zD2JLUCpp0mJG7JkwznIOzawhGmFFaxGoxAhQBEg -haP+E0KR66oAwVC6xe32QUVSHfWqWndzbODzLB8yj7WAR0cDM45ZngSBPBuFE3Wu -GLJX9g100ETfIX+4YBR/4NR/uvTnpnd9ete7Whl0ZfY94yuu4xQqB5QFv+P7IXXV -lTOjkjuGXEcyQAjQzbFaT9vIABSbeCXWBbjvOXukJy6WgAiclzGNSYprre8Ryydd -fmjW9HIGwsIO03EldivvqEYL1Hv1w/Pur+6FUEOaL68PEIUovfgwIB2BAw+vZDuw -cH0mX548PojGyg434cDjkSXa3mHF ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN -MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw -ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL -SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50 -cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC -AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk -9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi -8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG -yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM -vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE -CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2 -J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF -BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap -aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl -BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT -2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO -fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5 -UNkAAk/bg9ART6RCVmE6fhMy04Qfybo= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEGjCCAwKgAwIBAgIDAYagMA0GCSqGSIb3DQEBBQUAMIGjMQswCQYDVQQGEwJG -STEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0ZXJpa2Vz -a3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBTZXJ2aWNl -czEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJLIEdvdi4g -Um9vdCBDQTAeFw0wMjEyMTgxMzUzMDBaFw0yMzEyMTgxMzUxMDhaMIGjMQswCQYD -VQQGEwJGSTEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0 -ZXJpa2Vza3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBT -ZXJ2aWNlczEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJL -IEdvdi4gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCF -FdrIAzfQo0Y3bBseljDCWoUSZyPyu5/nioFgJ/gTqTy894aqqvTzJSm0/nWuHoGG -igWyHWWyOOi0zCia+xc28ZPVec7Bg4shT8MNrUHfeJ1I4x9CRPw8bSEga60ihCRC -jxdNwlAfZM0tOSJWiP2yY51U2kJpwMhP1xjiPshphJQ9LIDGfM6911Mf64i5psu7 -hVfvV3ZdDIvTXhJBnyHAOfQmbQj6OLOhd7HuFtjQaNq0mKWgZUZKa41+qk1guPjI -DfxxPu45h4G02fhukO4/DmHXHSto5i7hQkQmeCxY8n0Wf2HASSQqiYe2XS8pGfim -545SnkFLWg6quMJmQlMCAwEAAaNVMFMwDwYDVR0TAQH/BAUwAwEB/zARBglghkgB -hvhCAQEEBAMCAAcwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBTb6eGb0tEkC/yr -46Bn6q6cS3f0sDANBgkqhkiG9w0BAQUFAAOCAQEArX1ID1QRnljurw2bEi8hpM2b -uoRH5sklVSPj3xhYKizbXvfNVPVRJHtiZ+GxH0mvNNDrsczZog1Sf0JLiGCXzyVy -t08pLWKfT6HAVVdWDsRol5EfnGTCKTIB6dTI2riBmCguGMcs/OubUpbf9MiQGS0j -8/G7cdqehSO9Gu8u5Hp5t8OdhkktY7ktdM9lDzJmid87Ie4pbzlj2RXBbvbfgD5Q -eBmK3QOjFKU3p7UsfLYRh+cF8ry23tT/l4EohP7+bEaFEEGfTXWMB9SZZ291im/k -UJL2mdUQuMSpe/cXjUu/15WfCdxEDx4yw8DP03kN5Mc7h/CQNIghYkmSBAQfvA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz -IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz -MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj -dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw -EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp -MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 -28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq -VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q -DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR -5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL -ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a -Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl -UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s -+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 -Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj -ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx -hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV -HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 -+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN -YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t -L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy -ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt -IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV -HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w -DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW -PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF -5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 -glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH -FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 -pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD -xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG -tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq -jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De -fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg -OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ -d0jQ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD -VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 -IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 -MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD -aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx -MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy -cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG -A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl -BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed -KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 -G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 -zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 -ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG -HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 -Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V -yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e -beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r -6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh -wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog -zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW -BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr -ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp -ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk -cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt -YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC -CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow -KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI -hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ -UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz -X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x -fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz -a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd -Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd -SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O -AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso -M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge -v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z -09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx -NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv -bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA -VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku -WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX -5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ -ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg -h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV -BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE -CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy -MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G -A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD -DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq -M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf -OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa -4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 -HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR -aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA -b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ -Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV -PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO -pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu -UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY -MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 -9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW -s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 -Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg -cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM -79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz -/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt -ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm -Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK -QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ -w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi -S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 -mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz -WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 -b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS -b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI -7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg -CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD -VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T -kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ -gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE -BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK -DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz -OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R -xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX -qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC -C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 -6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh -/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF -YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E -JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc -US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 -ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm -+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi -M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G -A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV -cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc -Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs -PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ -q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 -cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr -a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I -H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y -K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu -nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf -oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY -Ic2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 -OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG -A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ -JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD -vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo -D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ -Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW -RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK -HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN -nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM -0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i -UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 -Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg -TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL -BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K -2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX -UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl -6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK -9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ -HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI -wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY -XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l -IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo -hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr -so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j -ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js -LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM -BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy -dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh -cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh -YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg -dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp -bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ -YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT -TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ -9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 -jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW -FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz -ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 -ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L -EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu -L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC -O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V -um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh -NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul -F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC -ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w -ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk -aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 -YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg -c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 -d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG -CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF -wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS -Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst -0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc -pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl -CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF -P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK -1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm -KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE -JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ -8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm -fyWl8kgAwKQB2j8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln -biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF -MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT -d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 -76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ -bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c -6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE -emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd -MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt -MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y -MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y -FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi -aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM -gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB -qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 -lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn -8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 -45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO -UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 -O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC -bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv -GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a -77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC -hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 -92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp -Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w -ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt -Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu -IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw -WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD -ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y -IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn -IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ -6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob -jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw -izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl -+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY -zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP -pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF -KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW -ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB -AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 -ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW -IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA -A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 -uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ -FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 -jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ -u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D -YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 -puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa -icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG -DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x -kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z -Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu -IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow -RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY -U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv -Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br -YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF -nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH -6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt -eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ -c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ -MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH -HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf -jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 -5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB -rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c -wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB -AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp -WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 -xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ -2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ -IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 -aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X -em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR -dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ -OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ -hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy -tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFSzCCAzOgAwIBAgIRALZLiAfiI+7IXBKtpg4GofIwDQYJKoZIhvcNAQELBQAw -PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTAeFw0xMjA5MjgwODU4NTFaFw0zNzEyMzExNTU5NTla -MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQC2/5c8gb4BWCQnr44BK9ZykjAyG1+bfNTUf+ihYHMwVxAA+lCWJP5Q5ow6ldFX -eYTVZ1MMKoI+GFy4MCYa1l7GLbIEUQ7v3wxjR+vEEghRK5lxXtVpe+FdyXcdIOxW -juVhYC386RyA3/pqg7sFtR4jEpyCygrzFB0g5AaPQySZn7YKk1pzGxY5vgW28Yyl -ZJKPBeRcdvc5w88tvQ7Yy6gOMZvJRg9nU0MEj8iyyIOAX7ryD6uBNaIgIZfOD4k0 -eA/PH07p+4woPN405+2f0mb1xcoxeNLOUNFggmOd4Ez3B66DNJ1JSUPUfr0t4urH -cWWACOQ2nnlwCjyHKenkkpTqBpIpJ3jmrdc96QoLXvTg1oadLXLLi2RW5vSueKWg -OTNYPNyoj420ai39iHPplVBzBN8RiD5C1gJ0+yzEb7xs1uCAb9GGpTJXA9ZN9E4K -mSJ2fkpAgvjJ5E7LUy3Hsbbi08J1J265DnGyNPy/HE7CPfg26QrMWJqhGIZO4uGq -s3NZbl6dtMIIr69c/aQCb/+4DbvVq9dunxpPkUDwH0ZVbaCSw4nNt7H/HLPLo5wK -4/7NqrwB7N1UypHdTxOHpPaY7/1J1lcqPKZc9mA3v9g+fk5oKiMyOr5u5CI9ByTP -isubXVGzMNJxbc5Gim18SjNE2hIvNkvy6fFRCW3bapcOFwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVZx3gnHosnMvFmOcdByYqhux0zTAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAJA75cJTQijq9TFOjj2Rnk0J -89ixUuZPrAwxIbvx6pnMg/y2KOTshAcOD06Xu29oRo8OURWV+Do7H1+CDgxxDryR -T64zLiNB9CZrTxOH+nj2LsIPkQWXqmrBap+8hJ4IKifd2ocXhuGzyl3tOKkpboTe -Rmv8JxlQpRJ6jH1i/NrnzLyfSa8GuCcn8on3Fj0Y5r3e9YwSkZ/jBI3+BxQaWqw5 -ghvxOBnhY+OvbLamURfr+kvriyL2l/4QOl+UoEtTcT9a4RD4co+WgN2NApgAYT2N -vC2xR8zaXeEgp4wxXPHj2rkKhkfIoT0Hozymc26Uke1uJDr5yTDRB6iBfSZ9fYTf -hsmL5a4NHr6JSFEVg5iWL0rrczTXdM3Jb9DCuiv2mv6Z3WAUjhv5nDk8f0OJU+jl -wqu+Iq0nOJt3KLejY2OngeepaUXrjnhWzAWEx/uttjB8YwWfLYwkf0uLkvw4Hp+g -pVezbp3YZLhwmmBScMip0P/GnO0QYV7Ngw5u6E0CQUridgR51lQ/ipgyFKDdLZzn -uoJxo4ZVKZnSKdt1OvfbQ/+2W/u3fjWAjg1srnm3Ni2XUqGwB5wH5Ss2zQOXlL0t -DjQG/MAWifw3VOTWzz0TBPKR2ck2Lj7FWtClTILD/y58Jnb38/1FoqVuVa4uzM8s -iTTa9g3nkagQ6hed8vbs ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw -NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv -b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD -VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F -VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 -7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X -Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ -/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs -81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm -dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe -Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu -sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 -pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs -slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ -arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD -VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG -9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl -dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj -TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed -Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 -Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI -OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 -vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW -t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn -HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx -SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y -IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB -pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h -IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG -A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU -cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid -RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V -seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme -9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV -EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW -hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ -DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD -ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I -/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf -ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ -yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts -L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN -zl/HHk484IkzlQsPpTLWPFp5LBk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig -Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk -MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg -Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD -VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy -dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ -QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq -1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp -2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK -DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape -az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF -3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 -oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM -g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 -mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh -8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd -BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U -nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw -DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX -dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ -MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL -/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX -CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa -ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW -2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 -N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 -Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB -As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp -5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu -1uwJ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD -VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk -MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y -IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV -BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw -IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy -dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig -RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb -3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA -BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 -3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou -owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ -wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF -ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf -BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ -MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv -civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 -AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F -hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 -soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI -WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi -tJ/X5g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL -ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx -MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc -MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ -AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH -iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj -vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA -0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB -OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ -BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E -FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 -GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW -zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 -1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE -f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F -jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN -ZetX2fNXlrtIzYE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx -MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg -Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ -iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa -/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ -jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI -HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 -sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w -gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw -KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG -AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L -URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO -H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm -I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY -iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI -MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x -FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz -MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv -cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz -Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO -0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao -wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj -7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS -8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT -BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg -JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 -6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ -3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm -D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS -CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 @@ -3695,6 +2186,1515 @@ aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFujCCBKKgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMCVVMx +HTAbBgNVBAoTFEFwcGxlIENvbXB1dGVyLCBJbmMuMS0wKwYDVQQLEyRBcHBsZSBD +b21wdXRlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIEFwcGxlIFJv +b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA1MDIxMDAwMTgxNFoXDTI1MDIx +MDAwMTgxNFowgYYxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBcHBsZSBDb21wdXRl +ciwgSW5jLjEtMCsGA1UECxMkQXBwbGUgQ29tcHV0ZXIgQ2VydGlmaWNhdGUgQXV0 +aG9yaXR5MSkwJwYDVQQDEyBBcHBsZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1e +eYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsq +wx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsV +WR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO +2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+ +H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeU +yS0CAwEAAaOCAi8wggIrMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlH +lHYJ/vRrjS5ApvdHTX8IXjCCASkGA1UdIASCASAwggEcMIIBGAYJKoZIhvdjZAUB +MIIBCTBBBggrBgEFBQcCARY1aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj +YXRlYXV0aG9yaXR5L3Rlcm1zLmh0bWwwgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFu +Y2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2Nl +cHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5k +IGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRp +ZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wRAYDVR0fBD0wOzA5oDegNYYz +aHR0cHM6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L3Jvb3Qu +Y3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0cHM6Ly93d3cuYXBw +bGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5L2Nhc2lnbmVycy5odG1sMA0GCSqG +SIb3DQEBBQUAA4IBAQCd2i0oWC99dgS5BNM+zrdmY06PL9T+S61yvaM5xlJNBZhS +9YlRASR5vhoy9+VEi0tEBzmC1lrKtCBe2a4VXR2MHTK/ODFiSF3H4ZCx+CRA+F9Y +m1FdV53B5f88zHIhbsTp6aF31ywXJsM/65roCwO66bNKcuszCVut5mIxauivL9Wv +Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961 +kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH +CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk +BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4 +Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl +cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0 +aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY +F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N +8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe +rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K +/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu +7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC +28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6 +lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E +nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB +0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09 +5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj +WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN +jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s +ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM +OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q +619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn +2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj +o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v +nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG +5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq +pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb +dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 +BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDQzCCAiugAwIBAgIQX/h7KCtU3I1CoxW1aMmt/zANBgkqhkiG9w0BAQUFADA1 +MRYwFAYDVQQKEw1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENB +IDIwNDgwHhcNMDQwNTE0MjAxNzEyWhcNMjkwNTE0MjAyNTQyWjA1MRYwFAYDVQQK +Ew1DaXNjbyBTeXN0ZW1zMRswGQYDVQQDExJDaXNjbyBSb290IENBIDIwNDgwggEg +MA0GCSqGSIb3DQEBAQUAA4IBDQAwggEIAoIBAQCwmrmrp68Kd6ficba0ZmKUeIhH +xmJVhEAyv8CrLqUccda8bnuoqrpu0hWISEWdovyD0My5jOAmaHBKeN8hF570YQXJ +FcjPFto1YYmUQ6iEqDGYeJu5Tm8sUxJszR2tKyS7McQr/4NEb7Y9JHcJ6r8qqB9q +VvYgDxFUl4F1pyXOWWqCZe+36ufijXWLbvLdT6ZeYpzPEApk0E5tzivMW/VgpSdH +jWn0f84bcN5wGyDWbs2mAag8EtKpP6BrXruOIIt6keO1aO6g58QBdKhTCytKmg9l +Eg6CTY5j/e/rmxrbU6YTYK/CfdfHbBcl1HP7R2RQgYCUTOG/rksc35LtLgXfAgED +o1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJ/PI +FR5umgIJFq0roIlgX9p7L6owEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEF +BQADggEBAJ2dhISjQal8dwy3U8pORFBi71R803UXHOjgxkhLtv5MOhmBVrBW7hmW +Yqpao2TB9k5UM8Z3/sUcuuVdJcr18JOagxEu5sv4dEX+5wW4q+ffy0vhN4TauYuX +cB7w4ovXsNgOnbFp1iqRe6lJT37mjpXYgyc81WhJDtSd9i7rp77rMKSsH0T8lasz +Bvt9YAretIpjsJyp8qS5UwGH0GikJ3+r/+n6yUA4iGe0OcaEb1fJU9u6ju7AQ7L4 +CYNu/2bPPu8Xs1gYJQk0XuPL1hS27PKSb3TkL4Eq1ZKR4OCXPDJoBYVL0fdX4lId +kxpUnwVwwEpxYB5DC2Ae/qPOgRnhCzU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0 +MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG +EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT +CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK +8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2 +98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb +2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC +ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi +Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB +o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl +ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD +AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL +AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd +foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M +cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq +8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp +hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk +Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U +AGegcQCCSA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGATCCA+mgAwIBAgIRAI9hcRW6eVgXjH0ROqzW264wDQYJKoZIhvcNAQELBQAw +RTEfMB0GA1UEAxMWQ29tU2lnbiBHbG9iYWwgUm9vdCBDQTEVMBMGA1UEChMMQ29t +U2lnbiBMdGQuMQswCQYDVQQGEwJJTDAeFw0xMTA3MTgxMDI0NTRaFw0zNjA3MTYx +MDI0NTVaMEUxHzAdBgNVBAMTFkNvbVNpZ24gR2xvYmFsIFJvb3QgQ0ExFTATBgNV +BAoTDENvbVNpZ24gTHRkLjELMAkGA1UEBhMCSUwwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCyKClzKh3rm6n1nvigmV/VU1D4hSwYW2ro3VqpzpPo0Ph3 +3LguqjXd5juDwN4mpxTpD99d7Xu5X6KGTlMVtfN+bTbA4t3x7DU0Zqn0BE5XuOgs +3GLH41Vmr5wox1bShVpM+IsjcN4E/hMnDtt/Bkb5s33xCG+ohz5dlq0gA9qfr/g4 +O9lkHZXTCeYrmVzd/il4x79CqNvGkdL3um+OKYl8rg1dPtD8UsytMaDgBAopKR+W +igc16QJzCbvcinlETlrzP/Ny76BWPnAQgaYBULax/Q5thVU+N3sEOKp6uviTdD+X +O6i96gARU4H0xxPFI75PK/YdHrHjfjQevXl4J37FJfPMSHAbgPBhHC+qn/014DOx +46fEGXcdw2BFeIIIwbj2GH70VyJWmuk/xLMCHHpJ/nIF8w25BQtkPpkwESL6esaU +b1CyB4Vgjyf16/0nRiCAKAyC/DY/Yh+rDWtXK8c6QkXD2XamrVJo43DVNFqGZzbf +5bsUXqiVDOz71AxqqK+p4ek9374xPNMJ2rB5MLPAPycwI0bUuLHhLy6nAIFHLhut +TNI+6Y/soYpi5JSaEjcY7pxI8WIkUAzr2r+6UoT0vAdyOt7nt1y8844a7szo/aKf +woziHl2O1w6ZXUC30K+ptXVaOiW79pBDcbLZ9ZdbONhS7Ea3iH4HJNwktrBJLQID +AQABo4HrMIHoMA8GA1UdEwEB/wQFMAMBAf8wgYQGA1UdHwR9MHswPKA6oDiGNmh0 +dHA6Ly9mZWRpci5jb21zaWduLmNvLmlsL2NybC9jb21zaWduZ2xvYmFscm9vdGNh +LmNybDA7oDmgN4Y1aHR0cDovL2NybDEuY29tc2lnbi5jby5pbC9jcmwvY29tc2ln +bmdsb2JhbHJvb3RjYS5jcmwwDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQCRZPY +DUhirGm6rgZbPvuqJpFQsTAfBgNVHSMEGDAWgBQCRZPYDUhirGm6rgZbPvuqJpFQ +sTANBgkqhkiG9w0BAQsFAAOCAgEAk1V5V9701xsfy4mfX+tP9Ln5e9h3N+QMwUfj +kr+k3e8iXOqADjTpUHeBkEee5tJq09ZLp/43F5tZ2eHdYq2ZEX7iWHCnOQet6Yw9 +SU1TahsrGDA6JJD9sdPFnNZooGsU1520e0zNB0dNWwxrWAmu4RsBxvEpWCJbvzQL +dOfyX85RWwli81OiVMBc5XvJ1mxsIIqli45oRynKtsWP7E+b0ISJ1n+XFLdQo/Nm +WA/5sDfT0F5YPzWdZymudMbXitimxC+n4oQE4mbQ4Zm718Iwg3pP9gMMcSc7Qc1J +kJHPH9O7gVubkKHuSYj9T3Ym6c6egL1pb4pz/uT7cT26Fiopc/jdqbe2EAfoJZkv +hlp/zdzOoXTWjiKNA5zmgWnZn943FuE9KMRyKtyi/ezJXCh8ypnqLIKxeFfZl69C +BwJsPXUTuqj8Fic0s3aZmmr7C4jXycP+Q8V+akMEIoHAxcd960b4wVWKqOcI/kZS +Q0cYqWOY1LNjznRt9lweWEfwDBL3FhrHOmD4++1N3FkkM4W+Q1b2WOL24clDMj+i +2n9Iw0lc1llHMSMvA5D0vpsXZpOgcCVahfXczQKi9wQ3oZyonJeWx4/rXdMtagAB +VBYGFuMEUEQtybI+eIbnp5peO2WAAblQI4eTy/jMVowe5tfMEXovV3sz9ULgmGb3 +DscLP1I= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw +PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu +MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx +GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL +MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf +HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh +gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW +v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue +Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr +9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt +6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 +MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl +Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 +ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq +hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p +iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC +dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL +kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL +hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz +OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDcTCCAlmgAwIBAgIVAOYJ/nrqAGiM4CS07SAbH+9StETRMA0GCSqGSIb3DQEB +BQUAMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGlj +emVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIgUk9PVCBDQTAeFw0xMTEyMDYx +MTEwNTdaFw0zMTEyMDYxMTEwNTdaMFAxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRcwFQYDVQQDDA5TWkFGSVIg +Uk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKxHL49ZMTml +6g3wpYwrvQKkvc0Kc6oJ5sxfgmp1qZfluwbv88BdocHSiXlY8NzrVYzuWBp7J/9K +ULMAoWoTIzOQ6C9TNm4YbA9A1jdX1wYNL5Akylf8W5L/I4BXhT9KnlI6x+a7BVAm +nr/Ttl+utT/Asms2fRfEsF2vZPMxH4UFqOAhFjxTkmJWf2Cu4nvRQJHcttB+cEAo +ag/hERt/+tzo4URz6x6r19toYmxx4FjjBkUhWQw1X21re//Hof2+0YgiwYT84zLb +eqDqCOMOXxvH480yGDkh/QoazWX3U75HQExT/iJlwnu7I1V6HXztKIwCBjsxffbH +3jOshCJtywcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFFOSo33/gnbwM9TrkmdHYTMbaDsqMA0GCSqGSIb3DQEBBQUA +A4IBAQA5UFWd5EL/pBviIMm1zD2JLUCpp0mJG7JkwznIOzawhGmFFaxGoxAhQBEg +haP+E0KR66oAwVC6xe32QUVSHfWqWndzbODzLB8yj7WAR0cDM45ZngSBPBuFE3Wu +GLJX9g100ETfIX+4YBR/4NR/uvTnpnd9ete7Whl0ZfY94yuu4xQqB5QFv+P7IXXV +lTOjkjuGXEcyQAjQzbFaT9vIABSbeCXWBbjvOXukJy6WgAiclzGNSYprre8Ryydd +fmjW9HIGwsIO03EldivvqEYL1Hv1w/Pur+6FUEOaL68PEIUovfgwIB2BAw+vZDuw +cH0mX548PojGyg434cDjkSXa3mHF +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgIBBDANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJLUjEN +MAsGA1UECgwES0lTQTEuMCwGA1UECwwlS29yZWEgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkgQ2VudHJhbDEWMBQGA1UEAwwNS0lTQSBSb290Q0EgMTAeFw0wNTA4MjQw +ODA1NDZaFw0yNTA4MjQwODA1NDZaMGQxCzAJBgNVBAYTAktSMQ0wCwYDVQQKDARL +SVNBMS4wLAYDVQQLDCVLb3JlYSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDZW50 +cmFsMRYwFAYDVQQDDA1LSVNBIFJvb3RDQSAxMIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAvATk+hM58DSWIGtsaLv623f/J/es7C/n/fB/bW+MKs0lCVsk +9KFo/CjsySXirO3eyDOE9bClCTqnsUdIxcxPjHmc+QZXfd3uOPbPFLKc6tPAXXdi +8EcNuRpAU1xkcK8IWsD3z3X5bI1kKB4g/rcbGdNaZoNy4rCbvdMlFQ0yb2Q3lIVG +yHK+d9VuHygvx2nt54OJM1jT3qC/QOhDUO7cTWu8peqmyGGO9cNkrwYV3CmLP3WM +vHFE2/yttRcdbYmDz8Yzvb9Fov4Kn6MRXw+5H5wawkbMnChmn3AmPC7fqoD+jMUE +CSVPzZNHPDfqAmeS/vwiJFys0izgXAEzisEZ2wIBA6MyMDAwHQYDVR0OBBYEFL+2 +J9gDWnZlTGEBQVYx5Yt7OtnMMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEF +BQADggEBABOvUQveimpb5poKyLGQSk6hAp3MiNKrZr097LuxQpVqslxa/6FjZJap +aBV/JV6K+KRzwYCKhQoOUugy50X4TmWAkZl0Q+VFnUkq8JSV3enhMNITbslOsXfl +BM+tWh6UCVrXPAgcrnrpFDLBRa3SJkhyrKhB2vAhhzle3/xk/2F0KpzZm4tfwjeT +2KM3LzuTa7IbB6d/CVDv0zq+IWuKkDsnSlFOa56ch534eJAx7REnxqhZvvwYC/uO +fi5C4e3nCSG9uRPFVmf0JqZCQ5BEVLRxm3bkGhKsGigA35vB1fjbXKP4krG9tNT5 +UNkAAk/bg9ART6RCVmE6fhMy04Qfybo= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEGjCCAwKgAwIBAgIDAYagMA0GCSqGSIb3DQEBBQUAMIGjMQswCQYDVQQGEwJG +STEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0ZXJpa2Vz +a3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBTZXJ2aWNl +czEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJLIEdvdi4g +Um9vdCBDQTAeFw0wMjEyMTgxMzUzMDBaFw0yMzEyMTgxMzUxMDhaMIGjMQswCQYD +VQQGEwJGSTEQMA4GA1UECBMHRmlubGFuZDEhMB8GA1UEChMYVmFlc3RvcmVraXN0 +ZXJpa2Vza3VzIENBMSkwJwYDVQQLEyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBT +ZXJ2aWNlczEZMBcGA1UECxMQVmFybWVubmVwYWx2ZWx1dDEZMBcGA1UEAxMQVlJL +IEdvdi4gUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALCF +FdrIAzfQo0Y3bBseljDCWoUSZyPyu5/nioFgJ/gTqTy894aqqvTzJSm0/nWuHoGG +igWyHWWyOOi0zCia+xc28ZPVec7Bg4shT8MNrUHfeJ1I4x9CRPw8bSEga60ihCRC +jxdNwlAfZM0tOSJWiP2yY51U2kJpwMhP1xjiPshphJQ9LIDGfM6911Mf64i5psu7 +hVfvV3ZdDIvTXhJBnyHAOfQmbQj6OLOhd7HuFtjQaNq0mKWgZUZKa41+qk1guPjI +DfxxPu45h4G02fhukO4/DmHXHSto5i7hQkQmeCxY8n0Wf2HASSQqiYe2XS8pGfim +545SnkFLWg6quMJmQlMCAwEAAaNVMFMwDwYDVR0TAQH/BAUwAwEB/zARBglghkgB +hvhCAQEEBAMCAAcwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBTb6eGb0tEkC/yr +46Bn6q6cS3f0sDANBgkqhkiG9w0BAQUFAAOCAQEArX1ID1QRnljurw2bEi8hpM2b +uoRH5sklVSPj3xhYKizbXvfNVPVRJHtiZ+GxH0mvNNDrsczZog1Sf0JLiGCXzyVy +t08pLWKfT6HAVVdWDsRol5EfnGTCKTIB6dTI2riBmCguGMcs/OubUpbf9MiQGS0j +8/G7cdqehSO9Gu8u5Hp5t8OdhkktY7ktdM9lDzJmid87Ie4pbzlj2RXBbvbfgD5Q +eBmK3QOjFKU3p7UsfLYRh+cF8ry23tT/l4EohP7+bEaFEEGfTXWMB9SZZ291im/k +UJL2mdUQuMSpe/cXjUu/15WfCdxEDx4yw8DP03kN5Mc7h/CQNIghYkmSBAQfvA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 +OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG +A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ +JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD +vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo +D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ +Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW +RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK +HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN +nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM +0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i +UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 +Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg +TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL +BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX +UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl +6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK +9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ +HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI +wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY +XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l +IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo +hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr +so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j +ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js +LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM +BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy +dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh +cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh +YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg +dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp +bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ +YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT +TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ +9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 +jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW +FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz +ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 +ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L +EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu +L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC +O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V +um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh +NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul +F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC +ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w +ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk +aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 +YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg +c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 +d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG +CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF +wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS +Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst +0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc +pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl +CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF +P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK +1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm +KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ +8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm +fyWl8kgAwKQB2j8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu +IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw +WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD +ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y +IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn +IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ +6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob +jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw +izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl ++zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY +zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP +pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF +KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW +ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB +AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 +ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW +IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA +A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 +uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ +FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 +jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ +u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D +YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 +puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa +icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG +DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x +kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z +Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFSzCCAzOgAwIBAgIRALZLiAfiI+7IXBKtpg4GofIwDQYJKoZIhvcNAQELBQAw +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xMjA5MjgwODU4NTFaFw0zNzEyMzExNTU5NTla +MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQC2/5c8gb4BWCQnr44BK9ZykjAyG1+bfNTUf+ihYHMwVxAA+lCWJP5Q5ow6ldFX +eYTVZ1MMKoI+GFy4MCYa1l7GLbIEUQ7v3wxjR+vEEghRK5lxXtVpe+FdyXcdIOxW +juVhYC386RyA3/pqg7sFtR4jEpyCygrzFB0g5AaPQySZn7YKk1pzGxY5vgW28Yyl +ZJKPBeRcdvc5w88tvQ7Yy6gOMZvJRg9nU0MEj8iyyIOAX7ryD6uBNaIgIZfOD4k0 +eA/PH07p+4woPN405+2f0mb1xcoxeNLOUNFggmOd4Ez3B66DNJ1JSUPUfr0t4urH +cWWACOQ2nnlwCjyHKenkkpTqBpIpJ3jmrdc96QoLXvTg1oadLXLLi2RW5vSueKWg +OTNYPNyoj420ai39iHPplVBzBN8RiD5C1gJ0+yzEb7xs1uCAb9GGpTJXA9ZN9E4K +mSJ2fkpAgvjJ5E7LUy3Hsbbi08J1J265DnGyNPy/HE7CPfg26QrMWJqhGIZO4uGq +s3NZbl6dtMIIr69c/aQCb/+4DbvVq9dunxpPkUDwH0ZVbaCSw4nNt7H/HLPLo5wK +4/7NqrwB7N1UypHdTxOHpPaY7/1J1lcqPKZc9mA3v9g+fk5oKiMyOr5u5CI9ByTP +isubXVGzMNJxbc5Gim18SjNE2hIvNkvy6fFRCW3bapcOFwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTVZx3gnHosnMvFmOcdByYqhux0zTAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAJA75cJTQijq9TFOjj2Rnk0J +89ixUuZPrAwxIbvx6pnMg/y2KOTshAcOD06Xu29oRo8OURWV+Do7H1+CDgxxDryR +T64zLiNB9CZrTxOH+nj2LsIPkQWXqmrBap+8hJ4IKifd2ocXhuGzyl3tOKkpboTe +Rmv8JxlQpRJ6jH1i/NrnzLyfSa8GuCcn8on3Fj0Y5r3e9YwSkZ/jBI3+BxQaWqw5 +ghvxOBnhY+OvbLamURfr+kvriyL2l/4QOl+UoEtTcT9a4RD4co+WgN2NApgAYT2N +vC2xR8zaXeEgp4wxXPHj2rkKhkfIoT0Hozymc26Uke1uJDr5yTDRB6iBfSZ9fYTf +hsmL5a4NHr6JSFEVg5iWL0rrczTXdM3Jb9DCuiv2mv6Z3WAUjhv5nDk8f0OJU+jl +wqu+Iq0nOJt3KLejY2OngeepaUXrjnhWzAWEx/uttjB8YwWfLYwkf0uLkvw4Hp+g +pVezbp3YZLhwmmBScMip0P/GnO0QYV7Ngw5u6E0CQUridgR51lQ/ipgyFKDdLZzn +uoJxo4ZVKZnSKdt1OvfbQ/+2W/u3fjWAjg1srnm3Ni2XUqGwB5wH5Ss2zQOXlL0t +DjQG/MAWifw3VOTWzz0TBPKR2ck2Lj7FWtClTILD/y58Jnb38/1FoqVuVa4uzM8s +iTTa9g3nkagQ6hed8vbs +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDjjCCAnagAwIBAgIIKv++n6Lw6YcwDQYJKoZIhvcNAQEFBQAwKDELMAkGA1UE BhMCQkUxGTAXBgNVBAMTEEJlbGdpdW0gUm9vdCBDQTIwHhcNMDcxMDA0MTAwMDAw WhcNMjExMjE1MDgwMDAwWjAoMQswCQYDVQQGEwJCRTEZMBcGA1UEAxMQQmVsZ2l1 @@ -3717,37 +3717,6 @@ sauBQeYNxUJpU4c5nUwfAA4+Bw11V0SoU7Q2dmSZ3G7rPUZuFF1eR1ONeE3gJ7uO hXY= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIFVTCCBD2gAwIBAgIEO/OB0DANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJj -aDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZpY2VzMSIwIAYDVQQLExlD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQDEw1BZG1pbi1Sb290LUNB -MB4XDTAxMTExNTA4NTEwN1oXDTIxMTExMDA3NTEwN1owbDELMAkGA1UEBhMCY2gx -DjAMBgNVBAoTBWFkbWluMREwDwYDVQQLEwhTZXJ2aWNlczEiMCAGA1UECxMZQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdGllczEWMBQGA1UEAxMNQWRtaW4tUm9vdC1DQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMvgr0QUIv5qF0nyXZ3PXAJi -C4C5Wr+oVTN7oxIkXkxvO0GJToM9n7OVJjSmzBL0zJ2HXj0MDRcvhSY+KiZZc6Go -vDvr5Ua481l7ILFeQAFtumeza+vvxeL5Nd0Maga2miiacLNAKXbAcUYRa0Ov5VZB -++YcOYNNt/aisWbJqA2y8He+NsEgJzK5zNdayvYXQTZN+7tVgWOck16Da3+4FXdy -fH1NCWtZlebtMKtERtkVAaVbiWW24CjZKAiVfggjsiLo3yVMPGj3budLx5D9hEEm -vlyDOtcjebca+AcZglppWMX/iHIrx7740y0zd6cWEqiLIcZCrnpkr/KzwO135GkC -AwEAAaOCAf0wggH5MA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIASBkTCBjjCBiwYI -YIV0AREDAQAwfzArBggrBgEFBQcCAjAfGh1UaGlzIGlzIHRoZSBBZG1pbi1Sb290 -LUNBIENQUzBQBggrBgEFBQcCARZEaHR0cDovL3d3dy5pbmZvcm1hdGlrLmFkbWlu -LmNoL1BLSS9saW5rcy9DUFNfMl8xNl83NTZfMV8xN18zXzFfMC5wZGYwfwYDVR0f -BHgwdjB0oHKgcKRuMGwxFjAUBgNVBAMTDUFkbWluLVJvb3QtQ0ExIjAgBgNVBAsT -GUNlcnRpZmljYXRpb24gQXV0aG9yaXRpZXMxETAPBgNVBAsTCFNlcnZpY2VzMQ4w -DAYDVQQKEwVhZG1pbjELMAkGA1UEBhMCY2gwHQYDVR0OBBYEFIKf+iNzIPGXi7JM -Tb5CxX9mzWToMIGZBgNVHSMEgZEwgY6AFIKf+iNzIPGXi7JMTb5CxX9mzWTooXCk -bjBsMQswCQYDVQQGEwJjaDEOMAwGA1UEChMFYWRtaW4xETAPBgNVBAsTCFNlcnZp -Y2VzMSIwIAYDVQQLExlDZXJ0aWZpY2F0aW9uIEF1dGhvcml0aWVzMRYwFAYDVQQD -Ew1BZG1pbi1Sb290LUNBggQ784HQMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B -AQUFAAOCAQEAeE96XCYRpy6umkPKXDWCRn7INo96ZrWpMggcDORuofHIwdTkgOeM -vWOxDN/yuT7CC3FAaUajbPRbDw0hRMcqKz0aC8CgwcyIyhw/rFK29mfNTG3EviP9 -QSsEbnelFnjpm1wjz4EaBiFjatwpUbI6+Zv3XbEt9QQXBn+c6DeFLe4xvC4B+MTr -a440xTk59pSYux8OHhEvqIwHCkiijGqZhTS3KmGFeBopaR+dJVBRBMoXwzk4B3Hn -0Zib1dEYFZa84vPJZyvxCbLOnPRDJgH6V2uQqbG+6DXVaf/wORVOvF/wzzv0viM/ -RWbEtJZdvo8N3sdtCULzifnxP/V0T9+4ZQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV diff --git a/etc/Java.pem b/etc/Java.pem index 7caadbf..7c7c3fb 100644 --- a/etc/Java.pem +++ b/etc/Java.pem @@ -1,9 +1,6 @@ -Keystore-Typ: JKS -Keystore-Provider: SUN -Keystore enthält 89 Einträge -Aliasname: actalisauthenticationrootca [jdk] -Erstellungsdatum: 22.09.2011 -Eintragstyp: trustedCertEntry +Keystore type: JKS +Keystore provider: SUN +Your keystore contains 89 entries -----BEGIN CERTIFICATE----- MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w @@ -37,9 +34,6 @@ ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== -----END CERTIFICATE----- -Aliasname: addtrustexternalca [jdk] -Erstellungsdatum: 30.05.2000 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs @@ -65,9 +59,6 @@ Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- -Aliasname: addtrustqualifiedca [jdk] -Erstellungsdatum: 30.05.2000 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 @@ -93,9 +84,6 @@ P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no xqE= -----END CERTIFICATE----- -Aliasname: affirmtrustcommercialca [jdk] -Erstellungsdatum: 29.01.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz @@ -116,9 +104,6 @@ Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= -----END CERTIFICATE----- -Aliasname: affirmtrustnetworkingca [jdk] -Erstellungsdatum: 29.01.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz @@ -139,9 +124,6 @@ Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= -----END CERTIFICATE----- -Aliasname: affirmtrustpremiumca [jdk] -Erstellungsdatum: 29.01.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz @@ -173,9 +155,6 @@ GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e KeC2uAloGRwYQw== -----END CERTIFICATE----- -Aliasname: affirmtrustpremiumeccca [jdk] -Erstellungsdatum: 29.01.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ @@ -189,9 +168,6 @@ A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== -----END CERTIFICATE----- -Aliasname: amazonrootca1 [jdk] -Erstellungsdatum: 26.05.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 @@ -212,9 +188,6 @@ o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU 5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy rqXRfboQnoZsG4q5WTP468SQvvG5 -----END CERTIFICATE----- -Aliasname: amazonrootca2 [jdk] -Erstellungsdatum: 26.05.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 @@ -246,9 +219,6 @@ n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE 9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT 4PsJYGw= -----END CERTIFICATE----- -Aliasname: amazonrootca3 [jdk] -Erstellungsdatum: 26.05.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g @@ -261,9 +231,6 @@ ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM YyRIHN8wfdVoOw== -----END CERTIFICATE----- -Aliasname: amazonrootca4 [jdk] -Erstellungsdatum: 26.05.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g @@ -277,9 +244,6 @@ MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW 1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- -Aliasname: baltimorecybertrustca [jdk] -Erstellungsdatum: 12.05.2000 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD @@ -301,9 +265,6 @@ Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -Aliasname: buypassclass2ca [jdk] -Erstellungsdatum: 26.10.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg @@ -335,9 +296,6 @@ I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= -----END CERTIFICATE----- -Aliasname: buypassclass3ca [jdk] -Erstellungsdatum: 26.10.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg @@ -369,9 +327,6 @@ kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq 4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= -----END CERTIFICATE----- -Aliasname: camerfirmachambersca [jdk] -Erstellungsdatum: 01.08.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 @@ -414,9 +369,6 @@ fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ d0jQ -----END CERTIFICATE----- -Aliasname: camerfirmachamberscommerceca [jdk] -Erstellungsdatum: 30.09.2003 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL @@ -445,9 +397,6 @@ XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu tGWaIZDgqtCYvDi1czyL+Nw= -----END CERTIFICATE----- -Aliasname: camerfirmachambersignca [jdk] -Erstellungsdatum: 01.08.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 @@ -489,9 +438,6 @@ M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B -----END CERTIFICATE----- -Aliasname: certumca [jdk] -Erstellungsdatum: 11.06.2002 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD @@ -511,9 +457,6 @@ CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs 6GAqm4VKQPNriiTsBhYscw== -----END CERTIFICATE----- -Aliasname: certumtrustednetworkca [jdk] -Erstellungsdatum: 22.10.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D @@ -536,9 +479,6 @@ J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= -----END CERTIFICATE----- -Aliasname: chunghwaepkirootca [jdk] -Erstellungsdatum: 20.12.2004 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 @@ -572,9 +512,6 @@ Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D hNQ+IIX3Sj0rnP0qCglN6oH4EZw= -----END CERTIFICATE----- -Aliasname: comodoaaaca [jdk] -Erstellungsdatum: 01.01.2004 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow @@ -600,9 +537,6 @@ G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- -Aliasname: comodoeccca [jdk] -Erstellungsdatum: 06.03.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE @@ -619,9 +553,6 @@ BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- -Aliasname: comodorsaca [jdk] -Erstellungsdatum: 19.01.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G @@ -656,9 +587,6 @@ QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl 0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB NVOFBkpdn627G190 -----END CERTIFICATE----- -Aliasname: digicertassuredidg2 [jdk] -Erstellungsdatum: 01.08.2013 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 @@ -681,9 +609,6 @@ B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo IhNzbM8m9Yop5w== -----END CERTIFICATE----- -Aliasname: digicertassuredidg3 [jdk] -Erstellungsdatum: 01.08.2013 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu @@ -699,9 +624,6 @@ AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv 6pZjamVFkpUBtA== -----END CERTIFICATE----- -Aliasname: digicertassuredidrootca [jdk] -Erstellungsdatum: 10.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 @@ -724,9 +646,6 @@ NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- -Aliasname: digicertglobalrootca [jdk] -Erstellungsdatum: 10.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 @@ -749,9 +668,6 @@ PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- -Aliasname: digicertglobalrootg2 [jdk] -Erstellungsdatum: 01.08.2013 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 @@ -774,9 +690,6 @@ Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl MrY= -----END CERTIFICATE----- -Aliasname: digicertglobalrootg3 [jdk] -Erstellungsdatum: 01.08.2013 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu @@ -792,9 +705,6 @@ AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 sycX -----END CERTIFICATE----- -Aliasname: digicerthighassuranceevrootca [jdk] -Erstellungsdatum: 10.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 @@ -818,9 +728,6 @@ Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- -Aliasname: digicerttrustedrootg4 [jdk] -Erstellungsdatum: 01.08.2013 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 @@ -853,9 +760,6 @@ r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 /YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ -----END CERTIFICATE----- -Aliasname: dtrustclass3ca2 [jdk] -Erstellungsdatum: 05.11.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD @@ -881,9 +785,6 @@ zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y Johw1+qRzT65ysCQblrGXnRl11z+o+I= -----END CERTIFICATE----- -Aliasname: dtrustclass3ca2ev [jdk] -Erstellungsdatum: 05.11.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD @@ -909,9 +810,6 @@ CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 -----END CERTIFICATE----- -Aliasname: entrust2048ca [jdk] -Erstellungsdatum: 24.12.1999 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp @@ -937,9 +835,6 @@ u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er fF6adulZkMV8gzURZVE= -----END CERTIFICATE----- -Aliasname: entrustevca [jdk] -Erstellungsdatum: 27.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 @@ -967,9 +862,6 @@ AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m 0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -Aliasname: entrustrootcaec1 [jdk] -Erstellungsdatum: 18.12.2012 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 @@ -988,9 +880,6 @@ BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G -----END CERTIFICATE----- -Aliasname: entrustrootcag2 [jdk] -Erstellungsdatum: 07.07.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 @@ -1016,9 +905,6 @@ Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== -----END CERTIFICATE----- -Aliasname: entrustrootcag4 [jdk] -Erstellungsdatum: 27.05.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL @@ -1055,9 +941,6 @@ IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk 5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== -----END CERTIFICATE----- -Aliasname: geotrustglobalca [jdk] -Erstellungsdatum: 21.05.2002 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i @@ -1078,9 +961,6 @@ PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== -----END CERTIFICATE----- -Aliasname: geotrustprimaryca [jdk] -Erstellungsdatum: 27.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo @@ -1102,9 +982,6 @@ oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= -----END CERTIFICATE----- -Aliasname: geotrustprimarycag2 [jdk] -Erstellungsdatum: 05.11.2007 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj @@ -1122,9 +999,6 @@ CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz rD6ogRLQy7rQkgu2npaqBA+K -----END CERTIFICATE----- -Aliasname: geotrustprimarycag3 [jdk] -Erstellungsdatum: 02.04.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT @@ -1149,9 +1023,6 @@ AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G spki4cErx5z481+oghLrGREt -----END CERTIFICATE----- -Aliasname: geotrustuniversalca [jdk] -Erstellungsdatum: 04.03.2004 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy @@ -1183,9 +1054,6 @@ ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= -----END CERTIFICATE----- -Aliasname: globalsignca [jdk] -Erstellungsdatum: 01.09.1998 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv @@ -1207,9 +1075,6 @@ AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- -Aliasname: globalsigneccrootcar4 [jdk] -Erstellungsdatum: 13.11.2012 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH @@ -1223,9 +1088,6 @@ uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs ewv4n4Q= -----END CERTIFICATE----- -Aliasname: globalsigneccrootcar5 [jdk] -Erstellungsdatum: 13.11.2012 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH @@ -1240,9 +1102,6 @@ KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg 515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO xwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- -Aliasname: globalsignr3ca [jdk] -Erstellungsdatum: 18.03.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp @@ -1264,9 +1123,6 @@ mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE----- -Aliasname: globalsignrootcar6 [jdk] -Erstellungsdatum: 10.12.2014 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh @@ -1299,9 +1155,6 @@ JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R 8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= -----END CERTIFICATE----- -Aliasname: godaddyclass2ca [jdk] -Erstellungsdatum: 29.06.2004 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE @@ -1326,9 +1179,6 @@ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf ReYNnyicsbkqWletNw+vHX/bvZ8= -----END CERTIFICATE----- -Aliasname: godaddyrootg2ca [jdk] -Erstellungsdatum: 01.09.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT @@ -1352,9 +1202,6 @@ gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI 4uJEvlz36hz1 -----END CERTIFICATE----- -Aliasname: haricaeccrootca2015 [jdk] -Erstellungsdatum: 07.07.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl @@ -1372,9 +1219,6 @@ C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR -----END CERTIFICATE----- -Aliasname: haricarootca2015 [jdk] -Erstellungsdatum: 07.07.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k @@ -1410,9 +1254,6 @@ pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 vm9qp/UsQu0yrbYhnr68 -----END CERTIFICATE----- -Aliasname: identrustcommercial [jdk] -Erstellungsdatum: 16.01.2014 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu @@ -1444,9 +1285,6 @@ l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A 7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H -----END CERTIFICATE----- -Aliasname: identrustpublicca [jdk] -Erstellungsdatum: 16.01.2014 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu @@ -1478,9 +1316,6 @@ tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv 8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c -----END CERTIFICATE----- -Aliasname: letsencryptisrgx1 [jdk] -Erstellungsdatum: 04.06.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh @@ -1512,9 +1347,6 @@ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= -----END CERTIFICATE----- -Aliasname: luxtrustglobalroot2ca [jdk] -Erstellungsdatum: 05.03.2015 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQEL BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV @@ -1548,9 +1380,6 @@ LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+ x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6 oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr -----END CERTIFICATE----- -Aliasname: luxtrustglobalrootca [jdk] -Erstellungsdatum: 17.03.2011 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDZDCCAkygAwIBAgICC7gwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCTFUx FjAUBgNVBAoTDUx1eFRydXN0IHMuYS4xHTAbBgNVBAMTFEx1eFRydXN0IEdsb2Jh @@ -1572,9 +1401,6 @@ BSTveUJO84ton+Ruy4KZycwq3FPCH3CDqyEPVrRI/98HIrOM+R2mBN8tAza53W/+ MYhm/2xtRDSvCHc+JtJy9LtHVpM8mGPhM7uZI5K1g3noHZ9nrWLWidb2/CfeMifL hNp3hSGhEiE= -----END CERTIFICATE----- -Aliasname: quovadisrootca [jdk] -Erstellungsdatum: 19.03.2001 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 @@ -1609,9 +1435,6 @@ mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK SnQ2+Q== -----END CERTIFICATE----- -Aliasname: quovadisrootca1g3 [jdk] -Erstellungsdatum: 12.01.2012 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc @@ -1643,9 +1466,6 @@ ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD -----END CERTIFICATE----- -Aliasname: quovadisrootca2 [jdk] -Erstellungsdatum: 24.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv @@ -1679,9 +1499,6 @@ ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y 4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza 8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u -----END CERTIFICATE----- -Aliasname: quovadisrootca2g3 [jdk] -Erstellungsdatum: 12.01.2012 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc @@ -1713,9 +1530,6 @@ KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M -----END CERTIFICATE----- -Aliasname: quovadisrootca3 [jdk] -Erstellungsdatum: 24.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv @@ -1754,9 +1568,6 @@ Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK 4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- -Aliasname: quovadisrootca3g3 [jdk] -Erstellungsdatum: 12.01.2012 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc @@ -1788,9 +1599,6 @@ DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 -----END CERTIFICATE----- -Aliasname: secomscrootca1 [jdk] -Erstellungsdatum: 30.09.2003 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t @@ -1811,9 +1619,6 @@ Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== -----END CERTIFICATE----- -Aliasname: secomscrootca2 [jdk] -Erstellungsdatum: 29.05.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe @@ -1835,9 +1640,6 @@ t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy 1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- -Aliasname: securetrustca [jdk] -Erstellungsdatum: 07.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x @@ -1860,9 +1662,6 @@ D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= -----END CERTIFICATE----- -Aliasname: sslrooteccca [jdk] -Erstellungsdatum: 12.02.2016 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T @@ -1879,9 +1678,6 @@ VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl -----END CERTIFICATE----- -Aliasname: sslrootevrsaca [jdk] -Erstellungsdatum: 31.05.2017 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE @@ -1916,9 +1712,6 @@ w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== -----END CERTIFICATE----- -Aliasname: sslrootrsaca [jdk] -Erstellungsdatum: 12.02.2016 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK @@ -1953,9 +1746,6 @@ nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY Ic2wBlX7Jz9TkHCpBB5XJ7k= -----END CERTIFICATE----- -Aliasname: starfieldclass2ca [jdk] -Erstellungsdatum: 29.06.2004 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp @@ -1980,9 +1770,6 @@ xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- -Aliasname: starfieldrootg2ca [jdk] -Erstellungsdatum: 01.09.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT @@ -2006,9 +1793,6 @@ sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 -----END CERTIFICATE----- -Aliasname: starfieldservicesrootg2ca [jdk] -Erstellungsdatum: 01.09.2009 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT @@ -2033,9 +1817,6 @@ iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn 0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN sSi6 -----END CERTIFICATE----- -Aliasname: swisssigngoldg2ca [jdk] -Erstellungsdatum: 25.10.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln @@ -2069,9 +1850,6 @@ Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- -Aliasname: swisssignplatinumg2ca [jdk] -Erstellungsdatum: 25.10.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu @@ -2105,9 +1883,6 @@ DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== -----END CERTIFICATE----- -Aliasname: swisssignsilverg2ca [jdk] -Erstellungsdatum: 25.10.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu @@ -2141,9 +1916,6 @@ OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- -Aliasname: teliasonerarootcav1 [jdk] -Erstellungsdatum: 18.10.2007 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv @@ -2174,9 +1946,6 @@ t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -Aliasname: thawteprimaryrootca [jdk] -Erstellungsdatum: 17.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf @@ -2202,9 +1971,6 @@ xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 jVaMaA== -----END CERTIFICATE----- -Aliasname: thawteprimaryrootcag2 [jdk] -Erstellungsdatum: 05.11.2007 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp @@ -2221,9 +1987,6 @@ DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== -----END CERTIFICATE----- -Aliasname: thawteprimaryrootcag3 [jdk] -Erstellungsdatum: 02.04.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf @@ -2249,9 +2012,6 @@ KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu MdRAGmI0Nj81Aa6sY6A= -----END CERTIFICATE----- -Aliasname: ttelesecglobalrootclass2ca [jdk] -Erstellungsdatum: 01.10.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd @@ -2275,9 +2035,6 @@ g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN 9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP BSeOE6Fuwg== -----END CERTIFICATE----- -Aliasname: ttelesecglobalrootclass3ca [jdk] -Erstellungsdatum: 01.10.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd @@ -2301,9 +2058,6 @@ WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p TpPDpFQUWw== -----END CERTIFICATE----- -Aliasname: usertrusteccca [jdk] -Erstellungsdatum: 01.02.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl @@ -2320,9 +2074,6 @@ VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= -----END CERTIFICATE----- -Aliasname: usertrustrsaca [jdk] -Erstellungsdatum: 01.02.2010 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl @@ -2357,9 +2108,6 @@ VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG jjxDah2nGN59PRbxYvnKkKj9 -----END CERTIFICATE----- -Aliasname: utnuserfirstobjectca [jdk] -Erstellungsdatum: 09.07.1999 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug @@ -2386,9 +2134,6 @@ mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU 81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= -----END CERTIFICATE----- -Aliasname: verisignclass3g3ca [jdk] -Erstellungsdatum: 01.10.1999 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl @@ -2413,9 +2158,6 @@ DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- -Aliasname: verisignclass3g4ca [jdk] -Erstellungsdatum: 05.11.2007 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW @@ -2437,9 +2179,6 @@ kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC 4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== -----END CERTIFICATE----- -Aliasname: verisignclass3g5ca [jdk] -Erstellungsdatum: 08.11.2006 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL @@ -2468,9 +2207,6 @@ WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq -----END CERTIFICATE----- -Aliasname: verisignuniversalrootca [jdk] -Erstellungsdatum: 02.04.2008 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL @@ -2499,9 +2235,6 @@ BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 7M2CYfE45k+XmCpajQ== -----END CERTIFICATE----- -Aliasname: xrampglobalca [jdk] -Erstellungsdatum: 01.11.2004 -Eintragstyp: trustedCertEntry -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk diff --git a/etc/Linux.pem b/etc/Linux.pem index c26874e..ab2430d 100644 --- a/etc/Linux.pem +++ b/etc/Linux.pem @@ -43,6 +43,38 @@ d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 @@ -116,6 +148,19 @@ olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG @@ -147,17 +192,80 @@ RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e KeC2uAloGRwYQw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC -VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ -cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ -BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt -VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D -0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 -ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G -A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs -aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I -flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE @@ -352,6 +460,73 @@ t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP @@ -372,6 +547,40 @@ i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN 9u6wWk5JRFRYX0KD -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU @@ -394,6 +603,38 @@ VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 @@ -502,6 +743,40 @@ fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE @@ -546,6 +821,43 @@ H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD @@ -568,6 +880,43 @@ YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j @@ -591,6 +940,38 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha @@ -672,6 +1053,78 @@ Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 @@ -697,6 +1150,85 @@ bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er fF6adulZkMV8gzURZVE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW @@ -757,6 +1289,21 @@ W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D hNQ+IIX3Sj0rnP0qCglN6oH4EZw= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV @@ -793,6 +1340,38 @@ y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 @@ -834,6 +1413,33 @@ v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw @@ -898,6 +1504,38 @@ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 @@ -945,6 +1583,111 @@ LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI 4uJEvlz36hz1 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX +mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 +zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P +fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc +vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 +Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp +zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO +Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW +k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ +DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF +lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW +Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z +XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR +gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 +d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv +J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg +DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM ++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy +F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 +SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws +E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH +MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM +QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy +MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl +cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg +GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu +XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd +re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu +PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 +mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K +8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj +x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR +nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 +kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok +twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp +8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT +z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA +pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb +pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB +R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R +RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk +0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC +5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF +izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn +yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A +DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk +fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA +njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l +xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 +CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx +sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p @@ -970,6 +1713,41 @@ Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI l7WdmplNsDz4SgCbZN2fOUvRJ9e4 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG @@ -990,6 +1768,133 @@ fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi AmvZWg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD @@ -1048,6 +1953,87 @@ tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl @@ -1095,6 +2081,105 @@ wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV @@ -1128,6 +2213,37 @@ ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y 8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV @@ -1325,6 +2441,189 @@ Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIUaxJdQjIDEN/QbdCHqoB/kCvsv68wDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVYnVzdGVyLmxhYmhhbWJ1cmcubGFuMB4XDTIwMDExNzEw +NTQyMFoXDTMwMDExNDEwNTQyMFowIDEeMBwGA1UEAwwVYnVzdGVyLmxhYmhhbWJ1 +cmcubGFuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxnLIp2kiiiLV +z5cXVBanG/a7f9B17PsxFj4M2609k82VJqWD2pEzDcaFOeE08Vf5ocxMi1cBSUOX +7IH5/bwbfegXlUSxhLTaVW8SjMpDJGysIT8UNb0IAaZKXrbKyyPaX/h6zio17sKi +Z+/78I+vBQjk1/QsZEML2xq2NyFJVu0nS1YYHcfDIarRaSuoZL+cPIc63Yv/dy0W +PYzuPL2XySmC2W11KJH+VDt6MqGpOpnNkydAZhEs5Nfm00qbA28zdH6Ao6/51Urv +34rgzZ+Cf+SuI0y0Aoa2+Wj64Wc9I1SacnS9NE9zIzzMV5TCIeJCqv2FHOnM3MIc +K1nlKs1NtwIDAQABoy8wLTAJBgNVHRMEAjAAMCAGA1UdEQQZMBeCFWJ1c3Rlci5s +YWJoYW1idXJnLmxhbjANBgkqhkiG9w0BAQsFAAOCAQEAbcoTnlSg1ksTLpBAzfNG +Eos8HDzcvngnjMRhCtYdFSN/5uaOpdaHb/Z+h/w65LlAWhGCKWSrI1F+UY6rPKiH +UW+NKBa1SvKOw3fKbGJoji++vIQIHiJSa/E+uiFkr9ywkBkrsR6OXTpJnISt4ttF +mw6QH/F4wxC70dkuOoQeTWIcFoIjESjltQh7uEsbns4Aj6hF4AvjfD8eY65KuGsR +RKPKmcccVjEb8jyRALNGJqM0wU1KmnvmbDfWhok8Nu6+6ihu8ZnemDjeXiSucTiG +d2EbX6l3LdqAIHGz6SWCYKaHmad3G92Haa5aLtPLROEUyR9NPY7VfLhwyxsC9x/H +bA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw @@ -1462,6 +2761,27 @@ hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD @@ -1492,1061 +2812,6 @@ HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL -ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx -MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc -MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ -AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH -iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj -vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA -0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB -OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ -BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E -FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 -GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW -zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 -1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE -f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F -jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN -ZetX2fNXlrtIzYE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB -gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk -MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY -UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx -NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 -dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy -dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 -38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP -KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q -DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 -qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa -JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi -PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P -BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs -jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 -eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD -ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR -vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa -IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy -i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ -O+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB -gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu -QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG -A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz -OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ -VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 -b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA -DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn -0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB -OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE -fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E -Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m -o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i -sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW -OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez -Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS -adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n -3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ -F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf -CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 -XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm -djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ -WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb -AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq -P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko -b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj -XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P -5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi -DrW5viSP ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG -A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 -d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu -dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq -RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy -MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD -VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g -Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD -ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi -A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt -ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH -Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC -R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX -hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 -cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs -IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz -dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy -NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu -dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt -dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 -aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T -RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN -cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW -wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 -U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 -jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN -BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ -jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v -1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R -nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH -VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN -BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl -bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv -b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ -BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj -YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 -MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 -dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg -QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa -jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi -C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep -lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof -TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix -DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k -IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT -N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v -dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG -A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh -ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx -QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA -4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 -AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 -4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C -ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV -9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD -gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 -Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq -NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko -LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd -ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I -XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI -M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot -9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V -Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea -j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh -X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ -l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf -bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 -pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK -e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 -vm9qp/UsQu0yrbYhnr68 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y -MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg -TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS -b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS -M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC -UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d -Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p -rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l -pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb -j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC -KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS -/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X -cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH -1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP -px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 -MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u -2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS -v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC -wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy -CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e -vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 -Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa -Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL -eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 -FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc -7uzXLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX -DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP -cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW -IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX -xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy -KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR -9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az -5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 -6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 -Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP -bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt -BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt -XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd -INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD -U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp -LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 -Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp -gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh -/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw -0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A -fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq -4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR -1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ -QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM -94B7IWcnMFk= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 -ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw -NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg -Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN -QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT -3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw -3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 -3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 -BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN -XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF -AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw -8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG -nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP -oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy -d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg -LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ -WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ -BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG -Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ -yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf -BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz -WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF -tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z -374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC -IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL -mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 -wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS -MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 -ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet -UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H -YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 -LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 -RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM -LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf -77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N -JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm -fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp -6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp -1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B -9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok -RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv -uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj -ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM -9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw -IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 -VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L -93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm -jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA -A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI -U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs -N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv -o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU -5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy -rqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK -gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ -W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg -1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K -8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r -2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me -z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR -8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj -mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz -7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 -+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI -0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm -UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 -LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS -k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl -7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm -btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl -urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ -fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 -n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE -76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H -9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT -4PsJYGw= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl -ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr -ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr -BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM -YyRIHN8wfdVoOw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi -9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk -M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB -MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw -CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW -1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE -BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 -MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV -BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w -HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj -Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj -TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u -KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj -qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm -MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 -ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP -zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk -L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC -jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA -HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC -AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm -DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 -COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry -L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf -JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg -IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io -2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV -09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ -XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq -T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe -MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx -NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv -bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA -VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku -WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX -5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ -ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg -h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV -BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE -CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy -MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G -A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD -DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq -M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf -OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa -4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 -HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR -aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA -b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ -Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV -PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO -pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu -UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY -MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 -9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW -s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 -Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg -cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM -79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz -/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt -ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm -Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK -QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ -w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi -S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 -mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz -WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 -b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS -b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI -7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg -CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD -VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T -kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ -gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE -BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK -DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz -OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R -xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX -qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC -C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 -6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh -/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF -YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E -JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc -US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 -ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm -+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi -M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G -A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV -cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc -Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs -PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ -q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 -cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr -a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I -H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y -K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu -nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf -oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY -Ic2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U @@ -2633,532 +2898,25 @@ As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp 1uwJ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx -GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp -bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w -KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 -BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy -dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG -EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll -IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU -QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT -TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg -LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 -a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr -LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr -N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X -YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ -iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f -AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH -V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf -IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 -lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c -8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf -lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg -MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx -MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET -MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI -xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k -ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD -aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw -LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw -1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX -k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 -SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h -bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n -WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY -rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce -MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu -bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt -Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 -55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj -vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf -cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz -oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp -nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs -pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v -JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R -8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 -5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw -CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 -bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg -Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ -BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu -ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS -b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni -eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W -p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T -rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV -57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg -Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw -WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw -MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x -MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD -VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX -BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO -ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M -CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu -I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm -TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh -C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf -ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz -IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT -Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k -JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 -hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB -GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov -L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo -dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr -aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq -hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L -6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG -HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 -0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB -lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi -o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 -gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v -faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 -Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh -jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw -3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG -EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx -IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND -IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci -MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti -sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O -BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB -Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c -3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J -0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG -EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo -bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g -RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ -TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s -b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 -WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS -fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB -zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq -hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB -CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD -+JbNR6iC8hZVdyR+EhCVBCyj ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG -A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg -SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw -MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln -biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v -dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ -BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ -HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH -3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH -GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c -xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 -aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq -TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 -/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 -kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG -YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT -+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo -WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD -VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU -ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH -MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO -MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv -Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz -f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO -8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq -d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM -tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt -Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB -o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x -PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM -wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d -GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH -6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby -RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw -gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL -Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg -MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw -BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 -MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 -c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ -bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ -2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E -T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j -5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM -C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T -DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX -wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A -2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm -nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl -N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj -c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS -5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS -Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr -hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ -B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI -AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw -H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ -b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk -2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol -IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk -5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY -n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM -f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX -mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 -zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P -fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc -vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 -Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp -zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO -Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW -k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ -DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF -lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW -Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 -d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z -XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR -gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 -d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv -J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg -DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM -+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy -F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 -SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws -E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH -MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM -QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy -MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl -cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv -CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg -GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu -XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd -re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu -PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 -mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K -8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj -x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR -nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 -kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok -twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp -8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT -vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT -z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA -pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb -pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB -R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R -RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk -0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC -5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF -izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn -yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout -736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A -DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk -fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA -njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu -hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l -xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 -CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx -sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL -BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ -SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n -a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 -NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT -CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u -Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO -dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI -VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV -9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY -2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY -vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt -bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb -x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ -l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK -TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj -Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e -i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw -DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG -7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk -MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr -gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk -GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS -3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm -Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ -l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c -JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP -L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa -LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG -mpv0 ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF -eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx -MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV -BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog -D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS -sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop -O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk -sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi -c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj -VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz -KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ -TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G -sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs -1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD -fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN -l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ -VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 -c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp -4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s -t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj -2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO -vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C -xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx -cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM -fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH -bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x -CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds -b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr -b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 -kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm -VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R -VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc -C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj -tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY -D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv -j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl -NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 -iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP -O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV -ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj -L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl -1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU -b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV -PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj -y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb -EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg -DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI -+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy -YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX -UB+K+wb1whnw0A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV -BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g -Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ -BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ -R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF -dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw -vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ -uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp -n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs -cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW -xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P -rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF -DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx -DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy -LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C -eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ -d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq -kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl -qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 -OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c -NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk -ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO -pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj -03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk -PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE -1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX -QRBdJ3NghVdJIgc= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV -BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk -LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv -b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ -BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg -THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v -IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv -xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H -Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB -eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo -jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ -+efcMQ== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD -VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw -MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy -b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR -ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb -hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 -FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV -L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB -iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl -MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N -aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ -Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 -ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 -HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm -gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ -jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc -aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG -YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 -W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K -UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH -+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q -W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC -LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC -gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 -tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh -SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 -TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 -pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR -xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp -GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 -dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN -AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB -RA+GsCyRxj3qrg+E ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM -BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG -T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx -CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD -b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA -iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH -38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE -HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz -kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP -szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq -vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf -nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG -YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo -0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a -CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K -AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I -36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN -qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj -cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm -+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL -hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe -lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 -p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 -piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR -LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX -5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO -dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul -9XXeifdy +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw @@ -3226,3 +2984,264 @@ AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu Sw== -----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- diff --git a/etc/Microsoft.pem b/etc/Microsoft.pem index 08e7681..e2fe993 100644 --- a/etc/Microsoft.pem +++ b/etc/Microsoft.pem @@ -566,6 +566,41 @@ w8k2SjTxF+KAryAhk5Qe5hXTVGLxtTgv48y5ZwSpuuXu+RBuyy5+E6+SFP7zJ3N7 OPxzbbm5iPZujAv1/P8JDrMtXnt145Ik4ubhWD5LKAN1axibRww= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIFrjCCA5agAwIBAgIQUJZucr0Q1oxPa8diP5xwODANBgkqhkiG9w0BAQsFADBx MQswCQYDVQQGEwJMVDErMCkGA1UEChMiU2thaXRtZW5pbmlvIHNlcnRpZmlrYXZp bW8gY2VudHJhczEZMBcGA1UECxMQQ0EgUk9PVCBTZXJ2aWNlczEaMBgGA1UEAxMR @@ -3371,22 +3406,37 @@ YP3xJwADvUsn27yclzdRK+V4tME2kBCM/z0A1LpIn0jKhzGa7cSaU9LdcxQ/CYKh XWVOTSbi -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIC+TCCAmKgAwIBAgIENvEbGTANBgkqhkiG9w0BAQUFADA2MQswCQYDVQQGEwJF -UzENMAsGA1UEChMERk5NVDEYMBYGA1UECxMPRk5NVCBDbGFzZSAyIENBMB4XDTk5 -MDMxODE0NTYxOVoXDTE5MDMxODE1MjYxOVowNjELMAkGA1UEBhMCRVMxDTALBgNV -BAoTBEZOTVQxGDAWBgNVBAsTD0ZOTVQgQ2xhc2UgMiBDQTCBnTANBgkqhkiG9w0B -AQEFAAOBiwAwgYcCgYEAmD+tGTaTPT7+dkIU/TVv8fqtInpY40bQXcZa+WItjzFe -/rQw/lB0rNadHeBixkndFBJ9cQusBsE/1waH4JCJ1uXjA7LyJ7GfM8iqazZKo8Q/ -eUGdiUYvKz5j1DhWkaodsQ1CdU3zh07jD03MtGy/YhOH6tCbjrbi/xn0lAnVlmEC -AQOjggEUMIIBEDARBglghkgBhvhCAQEEBAMCAAcwWAYDVR0fBFEwTzBNoEugSaRH -MEUxCzAJBgNVBAYTAkVTMQ0wCwYDVQQKEwRGTk1UMRgwFgYDVQQLEw9GTk1UIENs -YXNlIDIgQ0ExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5OTAzMTgxNDU2 -MTlagQ8yMDE5MDMxODE0NTYxOVowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFECa -dkSXdAfErBTLHo1POkV8MNdhMB0GA1UdDgQWBBRAmnZEl3QHxKwUyx6NTzpFfDDX -YTAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG -SIb3DQEBBQUAA4GBAGFMoHxZY1tm+O5lE85DgEe5sjXJyITHa3NgReSdN531jiW5 -+aqqyuP4Q5wvoIkFsUUylCoeA41dpt7PV5Xa3yZgX8vflR64zgjY+IrJT6lodZPj -LwVMZGACokIeb4ZoZVUO2ENv8pExPqNHPCgFr0W2nSJMJntLfVsV+RlG3whd +MIIFwzCCA6ugAwIBAgIEBfXhAjANBgkqhkiG9w0BAQ0FADB4MSEwHwYDVQQDDBhJ +LkNBIFJvb3QgQ0EvUlNBIDA1LzIwMjIxLTArBgNVBAoMJFBydm7DrSBjZXJ0aWZp +a2HEjW7DrSBhdXRvcml0YSwgYS5zLjEXMBUGA1UEYQwOTlRSQ1otMjY0MzkzOTUx +CzAJBgNVBAYTAkNaMB4XDTIyMDUwMzEyMDUwMFoXDTQ3MDUwMzEyMDUwMFoweDEh +MB8GA1UEAwwYSS5DQSBSb290IENBL1JTQSAwNS8yMDIyMS0wKwYDVQQKDCRQcnZu +w60gY2VydGlmaWthxI1uw60gYXV0b3JpdGEsIGEucy4xFzAVBgNVBGEMDk5UUkNa +LTI2NDM5Mzk1MQswCQYDVQQGEwJDWjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC +AgoCggIBALI/FKJKQK/bDCQ4rD4u2Y3X3Zo4vey4yPbde1t0CRgVlZnR1y5inR4v +B41NFBxi/QOVsos0n68i/Ap2yI8TJWrOTxKCo6gELj1H4cL7zJ4XrheMdbQZ9bkM +3j5jbg1dg1fU+zjmQjLPJbQyk9sImf/eq7x/hjPsNr1Uo2Mz1XBa6KY7Svmlx2Bt ++P22IptmGAgANpZO91s5TwfHXBJCUSG5s5xr/CdKd/AeXAlh1d7bcfhjkBEMyaAc +ILqK/TKOh9L8rFKt94s2a98qPXFKIh5fof/qp6hzlIGrnJMibK0g8uEJGv9vqQgd +ECQ4tJfAF+b2vAFHtYsrBEbH9uxYmu01SKa0KK5XzVvpvHhdm6AnEPG3wSnkKnot +eITnS765oxryT6xz9c+E0sO+B3Mau8bdHUUOLwc0Mprn17esgEyGFaivx21NdKRh +7hrBoEqTgo4jrS9C+ipqM1x+jbKudDxDG7rv2GQOnJkHctxkUSEh7clq7rrwetU1 +A/x4Udr2EC+lOhEhse0FS9ffLsux1NpyJv4fEr1n+fg/P4CzrowIpiB+8UTPBAkF +afjbUFkLQ5GdNZMkAbkyVBZSC5HdBA9/JmHT/I+lgGzQVUwaL6hba2W+Li3bQB04 +o6OXj9gLWjmqdSHEiYB9qWXN/dXwPgRwmJyjaBr2syfSVjHo6PZnAgMBAAGjVTBT +MBEGA1UdIAQKMAgwBgYEVR0gADAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQU+87+8S3hiIuKF0aIaqm67qoibOcwDQYJKoZIhvcNAQEN +BQADggIBAFnSddf9L7Ll0uqS+B5+t4vG9c0FigKTOqbal7dfZTbzlxLmd2lMT+97 +FAkcb7KaXpzSW3ofw0/4yqRxS2RHYwKGzcetZPBho33tgWd+Sq4WB8vcYSpFwnwg +7SCFKMNbIQskQJoyLHPQAeEZ6NZd4Tsn+UfRvvuKpHCakYXiw2SNRZrWfwCkmEpE +Cc2wjQPqcwhpuw4POYHdUFlehLVsJJvVRrT8cjuarM86G5RFNUN3mt9o7cAtlRom +kbZwHymWkkyTDP0wCanfu09krPdxiHgj9Ti5y+/H6+akmSWuwARvwuY5y47Sxv4e +0Icc4HJyzZLduzMMGLn93gVe5SXC6ika3wp2fP+FakFYKUlFO8hqUVSl6Mx+rmzz +hsCP2B5cSLFpxdQeomZEh7EZ+rxpb0wE0y9MR7ebn1NJHdoRouq+T2LYR5faoXH6 +EAh9GFnp8WpTnqogZiYouakkwjUnkpD77nSF0vaUHbiXOPDN6IujHRlT3bTlJu5u +/pNg3wJfEP7Dfh5EDvcSsNT8cTZU9pzoqgwQW/7jJ5jjILRQvNSczzUrKstlu4D2 +iRYfEo7YmOYWH/KH6n2FJkrZV2L2lxpwrVZz/DCjK6qklzSHBTDguFZ6JcNaPPlu +O21Zr2CPXwm5JhBwqzyAcF4/c7+vXjOtwYGxiLmIq1RZUjtQ1iJz -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGDDCCA/SgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCQVQx @@ -5423,6 +5473,22 @@ LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd 398znM/jra6O1I7mT1GvFpLgXPYHDw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIICdDCCAfqgAwIBAgIEBfXhAzAKBggqhkjOPQQDAzB4MSEwHwYDVQQDDBhJLkNB +IFJvb3QgQ0EvRUNDIDA1LzIwMjIxLTArBgNVBAoMJFBydm7DrSBjZXJ0aWZpa2HE +jW7DrSBhdXRvcml0YSwgYS5zLjEXMBUGA1UEYQwOTlRSQ1otMjY0MzkzOTUxCzAJ +BgNVBAYTAkNaMB4XDTIyMDUwMzEyMTAwMFoXDTQ3MDUwMzEyMTAwMFoweDEhMB8G +A1UEAwwYSS5DQSBSb290IENBL0VDQyAwNS8yMDIyMS0wKwYDVQQKDCRQcnZuw60g +Y2VydGlmaWthxI1uw60gYXV0b3JpdGEsIGEucy4xFzAVBgNVBGEMDk5UUkNaLTI2 +NDM5Mzk1MQswCQYDVQQGEwJDWjB2MBAGByqGSM49AgEGBSuBBAAiA2IABMF8C82C +gbNtUNlAE2Vu34TjoDNT6kALav15eU0tqcTIPEOT33uvScANNFdLxOJWDJ74qxSU +2R7rU1zihlkzvOoXVsO+Xi1xaNwvxe5BKTzuAihf3FRPd/6YzMQMYwJSUaNVMFMw +EQYDVR0gBAowCDAGBgRVHSAAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBRAJ5B0QwXUzyfgd/MbKC28LUgm4TAKBggqhkjOPQQDAwNo +ADBlAjEA8ablZ3kU7ULAR/gNaBOnGJ4HYlzUgcoUXVVpZgWR+7vlHmeb15ASCLr7 +LuQMHHI2AjA/WMRr/DHG41fGi7b3mO0vtTVbiXxFTBWZfdwBnYg8B+xrP2X/HBsF +inSYcCkqYqI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIEgDCCA2igAwIBAgIBATANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UEBhMCQlIx EzARBgNVBAoTCklDUC1CcmFzaWwxPTA7BgNVBAsTNEluc3RpdHV0byBOYWNpb25h bCBkZSBUZWNub2xvZ2lhIGRhIEluZm9ybWFjYW8gLSBJVEkxNDAyBgNVBAMTK0F1 @@ -5706,38 +5772,6 @@ sr8vreNVMJ7fDkG84BH1oQyoIuHjAKNOcHyS4wTRekKKdZBZ45vRTKJkvXN5m2/y s8H2PA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y -MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg -TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS -b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS -M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC -UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d -Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p -rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l -pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb -j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC -KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS -/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X -cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH -1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP -px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 -MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u -2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS -v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC -wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy -CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e -vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 -Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa -Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL -eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 -FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc -7uzXLg== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg @@ -6301,6 +6335,39 @@ PFjJEodWE2EmHpEQQ3y8Hgw+0Fp8SX523G4BHUuSqdlm5Xod9LiLYC7slSz/TWTI 7CUAD9jzEqpL1/PSBmXeLdniE6YHskWu6g== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFyzCCA7OgAwIBAgIEBfXhBDANBgkqhkiG9w0BAQ0FADB8MSUwIwYDVQQDDBxJ +LkNBIFRMUyBSb290IENBL1JTQSAwNS8yMDIyMS0wKwYDVQQKDCRQcnZuw60gY2Vy +dGlmaWthxI1uw60gYXV0b3JpdGEsIGEucy4xFzAVBgNVBGEMDk5UUkNaLTI2NDM5 +Mzk1MQswCQYDVQQGEwJDWjAeFw0yMjA1MDMxMjE1MDBaFw00NzA1MDMxMjE1MDBa +MHwxJTAjBgNVBAMMHEkuQ0EgVExTIFJvb3QgQ0EvUlNBIDA1LzIwMjIxLTArBgNV +BAoMJFBydm7DrSBjZXJ0aWZpa2HEjW7DrSBhdXRvcml0YSwgYS5zLjEXMBUGA1UE +YQwOTlRSQ1otMjY0MzkzOTUxCzAJBgNVBAYTAkNaMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA1YKsEk5Juz5zQW0I+WJpnextUctdtjOUWoE/P7i8Of6L +Fie7QNBcUWaEWfm5srqCHh97Lvu8VNRI04fH0CSrkmxRNO24Pc7UWJmWwZhdnmi+ +W7/R+RpoMIZOaskGu33+LHxsvSyHHupPupaoPKEDyGTg9CMLWBU9ekRwa5oey2Bu +r7Zei8ssVj+RM1+/sJWz/64/8V/UoqKTDf0fP3ENjyTHDLT9xYSJx56Wx7AyNDlv +Zb2Fe97CjWkxPQ88+BVVq0giYc6JaRBqI/DA4DPtH28a01kcIQLwEs3e4ziz2Q4J +kyAXw2BF9MZ4jzypVZgEM7/JqODY2FXt1STEu+bQMRi89gCk7khB/SknDoTS6IkS +SK1uJkg89ULfm/Pxrgvz5ePm7NsbW9q8kH78/1NqQ8M5tPR5yLw8lmFk0gQj+opW +ojMUEhPqKD4Ifhun1HTBgsdySnt5LCyUKzEmPVyFssvQ5R6Jn44+mvOLC62AcAIZ +lRQjxPB/pYbaN1O7m8hFn6emvQops78HJdHHZZ2DgR+T7oNtZwDdboXNHxWti1ti +oYT9TXvtqwbagar3wEsiU1ncplKSxduegq/qkC/asnyJqhhy8ILes4r/ImUrzjtO +A94WlwzpSgvJLQaPSuVjpTUtYq4vwHXIsVoNQ7buCVoUkKCpokssNRrsrxDFnocC +AwEAAaNVMFMwEQYDVR0gBAowCDAGBgRVHSAAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRylXo7ia1RchFD/k/irzk6bQFoPzANBgkq +hkiG9w0BAQ0FAAOCAgEApE0ZHZ+HJoiPfOB6K14asF+UyzMiJ2MsGpyIflyKb4OW +0y39FuaLhYPVn5iGZnvRyobf/Jas2pkqQHY1TMajmN19Y/HwnHym3EZkcbmITW2+ +oVCU7NORiUOt6aEqRTcrEEJdPzgwVfHiW5bcWfqivRO1wJ/hVNldpr/f5iXZiLCf +1dO6Sq89eq0PYFu4PTUzwIGXgEm2WYZUO/pxjfoja9Vt5+OXWReb1IjeqkJDc1Wo +jYXUC+WKnEfxN8R77NvH3/o/qz8BpZbq7MPGhYWp7vvFel1m/K4Asac7WVq/VvLj +WO9cwy3vjMyFifBPgKN+lDvA3pCeYnko0sdFhAZlRv6drM7wix3q1vSwLiQB/462 +mTvZWaEZ2DyTCQSuFwWKZwdK6wZe32fhp7saSzel2Q+uzXG8YtLJgWwPIIj6YBRl +o/97WCoAaaIJR4GO+MgoXx7Q4ttyYySo5q22qpKwVoRA/y11ANtyeykE5amGpkbO +k/jo7+40znZDkrrhmPRzZFvcKDcX1zJHhun5+p6qMKOpiq0QpuYXOCVgC9VH6Ky5 +K8PmX0ort11ZBPLA2Fl06gs2h9A0YVdAwEtxh+c5MCltJY20KL6gPv5+ilqkM8x7 +Nor9gRi0ttpp5MRbXzXN/apX+UkAFid7k9dUlsTnc/wvlmOLq1eYP16/wB6XYV8= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIICFjCCAZ2gAwIBAgIQA2mP5xLVGfPO0P23sWQwETAKBggqhkjOPQQDAzBNMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERp Z2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYw @@ -6480,6 +6547,39 @@ wFXS+x56a0p2KSYS9q+kp7ztMqFw0/mNiweBpX0GwI3xNb62YLJvHiOikcr5YI3m 6JPv -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUf/Go+fQ66IduLcb/XkM9su4wpkMwDQYJKoZIhvcNAQEN +BQAwaTELMAkGA1UEBhMCVVMxFjAUBgNVBAoMDUVudHJ1c3QsIEluYy4xQjBABgNV +BAMMOUVudHJ1c3QgQ29kZSBTaWduaW5nIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkgLSBDU0JSMTAeFw0yMTA1MDcxMzI2MzZaFw00MDEyMzAxMzI2MzZaMGkx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKDA1FbnRydXN0LCBJbmMuMUIwQAYDVQQDDDlF +bnRydXN0IENvZGUgU2lnbmluZyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gQ1NCUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCngY/3FEW2 +YkPy2K7TJV5IT1G/xX2fUBw10dZ+YSqUGW0nRqSmGl33VFFqgCLGqGZ1TVSDyV5o +G6v2W2Swra0gvVTvRmttAudFrnX2joq5Mi6LuHccUk15iF+lOhjJUCyXJy2/2gB9 +Y3/vMuxGh2Pbmp/DWiE2e/mb1cqgbnIs/OHxnnBNCFYVb5Cr+0i6udfBgniFZS5/ +tcnA4hS3NxFBBuKK4Kj25X62eAUBw2DtTwdBLgoTSeOQm3/dvfqsv2RR0VybtPVc +51z/O5uloBrXfQmywrf/bhy8yH3m6Sv8crMU6UpVEoScRCV1HfYq8E+lID1oJeth +l3wP5bY9867DwRG8G47M4EcwXkIAhnHjWKwGymUfe5SmS1dnDH5erXhnW1XjXuvH +2OxMbobL89z4n4eqclgSD32m+PhCOTs8LOQyTUmM4OEAwjignPqEPkHcblauxhpb +9GdoBQHNG7+uh7ydU/Yu6LZr5JnexU+HWKjSZR7IH9Vybu5ZHFc7CXKd18q3kMbN +e0WSkUIDTH0/yvKquMIOhvMQn0YupGaGaFpoGHApOBGAYGuKQ6NzbOOzazf/5p1n +AZKG3y9I0ftQYNVc/iHTAUJj/u9wtBfAj6ju08FLXxLq/f0uDodEYOOp9MIYo+P9 +zgyEIg3zp3jak/PbOM+5LzPG/wc8Xr5F0wIDAQABo0IwQDAdBgNVHQ4EFgQUgrrW +PZfOn89x6JI3r/2ztWk1V88wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwDQYJKoZIhvcNAQENBQADggIBABLvOKGI4aGj1mXcR5zzvNzPrEuMPBq+K/T3 +0GcXaIZNcKjyzdAxAld9qQyKO1c5nvBu9yQiBWfRwZbBvtHw+FZnC96614ibjddr +CHb1WJHZtcNAUxqk8YXNPwBOP06TO3i50gdSZAyGaW3oVGVWF+gAU4SK89v7s84L +VWKPzUxJBjh/UsPzHNc99zPKMq3Bqa9v6xHL7qxRv7AmmnpOI7RK9mm0QmnWoI22 +jEdKOyA3t0EH7y8g2GYcaZeobDB8d0Nea74mmIMPOtbHcCoWRi0lVIZjZVdC9yNB +6VBqB0POTrXpH2jY2NYJSqjosvyQZ5LkkCbzR/rWIPuJgOJEczn3ioYzC/iqqedN +7Nxv1c8xTauOH5BA1nxcgg+uF1Jx6aznTTjtKth2eYetF6NMq7dCV78GrOXQTTDp +VU/jRcrz4GohNI3HnxyjY0iS0pYHvqVHPsIqmTinjtohfFFt3Ms9B+mpvUnUXTVf +W4wEUeqaWJC6G69oeLEWD5QpO4+bKo/JIPBxQkxcTasxjKvpfyZoaaClFg2BxNEF +DMOHZuUHY6obTv+yB0FPpSJGUKxmAIdSbDyyO5yXoUa0W97PwmpZVQeMo6TRdzVn +RgQv2Ti5Rq+6jhtyJgIvdlTvg8IvLHdwzHcQkqoDrcrM4E/pg0blszwZb3p5h7Y4 +mr1CzqRi +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv @@ -6519,6 +6619,23 @@ tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw +gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn +cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD +VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2 +NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r +YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh +IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF +Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ +KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK +fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB +Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C +MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp +ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6 +7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx +vmjkI6TZraE3 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH @@ -7840,6 +7957,36 @@ qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIFNDCCAxygAwIBAgIQdiQz69smdlqFYM0KqC/hFzANBgkqhkiG9w0BAQsFADA6 +MQswCQYDVQQGEwJJTjESMBAGA1UEChMJSW5kaWEgUEtJMRcwFQYDVQQDEw5DQ0Eg +SW5kaWEgMjAyMjAeFw0yMjAyMDIxMjA0MzdaFw00MjAyMDIxMjA0MzdaMDoxCzAJ +BgNVBAYTAklOMRIwEAYDVQQKEwlJbmRpYSBQS0kxFzAVBgNVBAMTDkNDQSBJbmRp +YSAyMDIyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv3EBudWC8HY0 +oSwtJZCqpjQTGpEewl3EdDqUORV0qoFp78mdR/vuATXI83G7nF9RLvmNjgQgKr/b +Mx6gPO4Y57bMjAsgwEzleFclZka/sqc68iN5rS3huhrCX6MEINLyDOQ71MRA7GJC +aNL6E3j1438eTu011mlikeZYBdkhvfpAVjCw90w8wcWDmqx66Y561T/RiXyz2uEh +BBZAD43gV58eXStOeOTwAzEZYMrmp232GfmQKabYRfdIRus1avyuGea2nICEsRHE +8M2tdzwpGP7oIy2qHBFJJ+3AwmwQA4DjmDkJtCD+58awohQavRNhqjsGD+ZifG3V +R4i6WrKv8OWqZzcZj3g3Elr5+fRMlz1GSqkWPBw1Ev8KWTHazSUKF7OMxm3XzyXx +Qnw7fZF9GOVtx3adpfRPqYGgtbOP34EVkz4wsHvNMrvUrYcKymdOrnkTjlX26fIH +UJpKGYkLk9q0jhMNKs4Rn8lj4pJ7YF33/ND4bjpV0ex1EAQz0iZvT37OnxNiuAZ/ ++4Djf075UuNX2ecWnadOrN1r8NAParZIwUoSUnWhU8TqAWWRqzFURHUZuOMQcA0g +eg4c9zqtBoUPgtQksbIAEsEXmDuRpwSIFjEkK11f5Eemfmfdg37KyIjQ67TRTmBA ++kT9Q5JIm/e7m1ILg/HKckgLUOCnAMsCAwEAAaM2MDQwDwYDVR0TAQH/BAUwAwEB +/zARBgNVHQ4ECgQITjtINlziX30wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +CwUAA4ICAQCdbE8d1c1DysKtrtYlApYIXTlY3N2XHNQ6gKoaVWsKa1TJ/ovrT+FV +3bmQLet3aSoEG6pTe/vLZSg8WiF7cn7WuF4XlQS3yA2Uu8/cg/S4owqhQJp6K/Xg +6UoSBad9Kog1H8deOfV8Nmb8a89zB4Yf8/AepId+Lr/3I6O7iub+PUT2QBXnksa+ +cf0yf+49GhyMCILZvctNSQd4Vxr9EgRvBARTrAgNQ9sEOJ6myOz4iTFR7T2pIFP8 +Cp15e8jEVI1q4IuHu3XlwJNk9f5k3gbwrzoy9P5rP8voQU3u9wh62JZa9U63b+u/ +Ur1tsKb5Lx0YUedtHvpIiIRurEPxumW0twjrx8TrAcXRrViSL7dsXAoYC0dXo154 +EE8jBAzgIIur7tJizxgXDEn4i2pu8Yd615YML9ii5BooEJ2j6fQ0nzyPRmx1Egw2 +Fjlgzzceai4TUOcaCKab86yyu5MZIp+BiPR840nw5MggbRgYH2nFRBA70toVm4VF +lbZs3reGmaICm4ST6R395OxYS1iYBm5kXm9tLb4pkIhUxrkgyuiwE+DsWceBjHAY +aXnCgUGKtiG9tfBMUw3fChoPb9L1yKdNof3zXDdTloMqEpO4BFrmjco8kt1v0LUQ +PhNZmQP4nqd4Hqx2384nPmWDXbQ+eePyxRteYGY0hJeDLVpyeYG8VQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD @@ -11043,6 +11190,40 @@ MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu Sw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQEL +BQAwgYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUt +VHVncmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYw +JAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIFJTQSB2MzAeFw0yMDAzMTgw +OTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMG +QW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 +Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBD +QSBSU0EgdjMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J7 +7gnJY9LTQ91ew6aEOErxjYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscx +uj7X/iWpKo429NEvx7epXTPcMHD4QGxLsqYxYdE0PD0xesevxKenhOGXpOhL9hd8 +7jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF/YP9f4RtNGx/ardLAQO/ +rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8qQedmCeFL +l+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bG +wzrwbMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4 +znKS4iicvObpCdg604nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBO +M/J+JjKsBY04pOZ2PJ8QaQ5tndLBeSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK +5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiMbIedBi3x7+PmBvrFZhNb/FAH +nnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbgh3cXTJ2w2Amo +DVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSy +tK7mLfcm1ap1LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEL +BQADggIBAImocn+M684uGMQQgC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ +6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN438o2Fi+CiJ+8EUdPdk3ILY7r3y18 +Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/qln0F7psTpURs+APQ +3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3sSdPk +vmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn9 +9t2HVhjYsCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQ +mhty3QUBjYZgv6Rn7rWlDdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YA +VSgU7NbHEqIbZULpkejLPoeJVF3Zr52XnGnnCv8PWniLYypMfUeUP95L6VPQMPHF +9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFHIK+WEj5jlB0E5y67hscM +moi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiXYY60MGo8 +bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIDHzCCAgegAwIBAgIEGZk8PzANBgkqhkiG9w0BAQUFADAiMQswCQYDVQQGEwJD TjETMBEGA1UEChMKQ0ZDQSBHVCBDQTAeFw0xMTA2MTMwODE1MDlaFw0yNjA2MDkw ODE1MDlaMCIxCzAJBgNVBAYTAkNOMRMwEQYDVQQKEwpDRkNBIEdUIENBMIIBIjAN @@ -11098,6 +11279,40 @@ fMF6uEV6XRflSpMbVGQI8MGsnVWUbyJCAEZlkcglGekXrfhckLqohDuU6nO83BAj V+M= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIGRCnTs8Z9MA0GCSqGSIb3DQEBCwUAMIGLMQswCQYDVQQG +EwJDQTErMCkGA1UEChMiQ2FyaWxsb24gSW5mb3JtYXRpb24gU2VjdXJpdHkgSW5j +LjEiMCAGA1UECxMZQ2VydGlmaWNhdGlvbiBBdXRob3JpdGllczErMCkGA1UEAxMi +Q2FyaWxsb24gUEtJIFNlcnZpY2VzIEcyIFJvb3QgQ0EgMTAeFw0yMDAxMjAxOTQy +NDVaFw00MDAxMjAxOTQyNDVaMIGLMQswCQYDVQQGEwJDQTErMCkGA1UEChMiQ2Fy +aWxsb24gSW5mb3JtYXRpb24gU2VjdXJpdHkgSW5jLjEiMCAGA1UECxMZQ2VydGlm +aWNhdGlvbiBBdXRob3JpdGllczErMCkGA1UEAxMiQ2FyaWxsb24gUEtJIFNlcnZp +Y2VzIEcyIFJvb3QgQ0EgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AMO5XBmVDlHyw4pIktk28Uy7Tdecwcxf2ogVKDW332xN1UmsGMXryGl2xr/ZN3JI +0lBx6WibzlF7rZk2b3PjYInZe0/Q6AYOVYybGNZc7ywdKyBKjw2YPRZNgxgbadEE +bpl8ClR2cTy/PrZSOSGF+6QBPuBSuNhmhg2gu2AUXhTyGcWHFRjpXC4G67eWLVK4 +CE1+t9KdgnvHXMTotK+9CGee/S8xszVwIl2bxdEoh7xW5LcEEp6bueL2JnSzG9OY +ABrtkqIgzl6IRtasVPtLZWXc3QD0EZftiosUaC3nYLdylHfn27qyoL5A6BpitahO +Qv0LqnCD6dkmAlKXMT0knuSaDnO9GQwGmlETyqegDh8bQ5XT+mylki8UQi4RLk+b +MA/jY7cRLDep8Zn/F0KT/bhnjZ0gK3i5G+OzV8ht1i+SJ05zps7ILGt4rcJnIP9T +xkbh3seyf5QCnStn5J+PwnHvesWBSxQ8i6mMh2Gkv8SsUxqlz0yT7ULwbydPHHdq +0QbzoB/fiJy4drIO0tfn2vlDXhEU5BlGgb1d04jv3ynH9lW/ziTy0gH4Opjp+r2Y +9oDv/dS6xVIe+VuBuy/xC3LoulsC2FGWgZPrfELhC89BWTSRqo32LmrhB199DtQe +cPPivHXG4iL0mSbVy+04l6RFNtbK/YuNqtdlAWDETWKDAgMBAAGjQjBAMB0GA1Ud +DgQWBBQ9YZY5F/sQgP8aaFhl/OkDGVYe+TAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBxjANBgkqhkiG9w0BAQsFAAOCAgEAftnQq/XkiRe7lRfAK5p1y+O1 +3XxbJCLrhr6R6y9aF7dsFzKiw2c+98978ihULzmi7UueTHINSBGcnF6p+2Mn/37D +25MD7LjzJg5sZ99yQtQL89WS9w1fL72NnzIGasrNZ/Bcn8tujbgVE+ppyO05WME9 +NuoJr0sqVEgnyB0tv+1saYq9WqGMf2I9kN+UUClZyzZhXfvpqLcik6KVnjEX9p0d +DdARB9pFL+HLqc7ppkwzzJ9RVDMG8Ak7tNJvXTlkslcDnrtNXfk16VDTqLfDHA2b +R8QAg8nk7gbLtXU53OhXCQsZlY3RFaZVpj2SF2tzd8jDxid1tAhaEr5AukcxNfMn +UUx9pdQOJqIWXKWSL7rabwvilc4QHjuLhopVkrxbtO+ocbki3DE039syuJtRchPa +wr1FNdeFJgQMnpOu8r9nU7NKpyndE3tJBq0Zt3Ic/+049lcS9hp2lnYFd0BmAayD +fOVgduDlbHaPo4Z3wmfH5rrxCjH4ANwtejD5ehQDIaCTnlJXNZwxX34IxTh7W/3p +5Ce8cmXXLS3lD5BauFsSJ5ZDBQFdUgk4c4XbInLUVKKAutKccNeDwIDtnfrJB7rj +0xU4BLl+FAyNNvHcuEW6yn3sAvaOxwLxtk3mpqrxx+Nt+blrhIW8kRG0NDKgVyHA +PnqXWpa1VrLSGwWKBLU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ diff --git a/etc/Mozilla.pem b/etc/Mozilla.pem index 26f1350..2ae7b6c 100644 --- a/etc/Mozilla.pem +++ b/etc/Mozilla.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Apr 26 03:12:05 2022 GMT +## Certificate data from Mozilla as of: Tue Jan 10 04:12:06 2023 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 34a54d5191775c1bd37be6cfd3f09e831e072555dc3a2e51f4a2c4b0f8ada5cc +## SHA256: 90c470e705b4b5f36f09684dc50e2b79c8b86989a848b62cd1a7bd6460ee65f6 ## @@ -489,29 +489,6 @@ IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== -----END CERTIFICATE----- -Network Solutions Certificate Authority -======================================= ------BEGIN CERTIFICATE----- -MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG -EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr -IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx -MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu -MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx -jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT -aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT -crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc -/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB -AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv -bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA -A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q -4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ -GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv -wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD -ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey ------END CERTIFICATE----- - COMODO ECC Certification Authority ================================== -----BEGIN CERTIFICATE----- @@ -993,30 +970,6 @@ tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- -Hellenic Academic and Research Institutions RootCA 2011 -======================================================= ------BEGIN CERTIFICATE----- -MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT -O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y -aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT -AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z -IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo -IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI -1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa -71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u -8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH -3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ -MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 -MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu -b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt -XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 -TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD -/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N -7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 ------END CERTIFICATE----- - Actalis Authentication Root CA ============================== -----BEGIN CERTIFICATE----- @@ -1678,36 +1631,6 @@ uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- -Staat der Nederlanden EV Root CA -================================ ------BEGIN CERTIFICATE----- -MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE -CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g -RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M -MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl -cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk -SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW -O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r -0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 -Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV -XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr -08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV -0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd -74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx -fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa -ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI -eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu -c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq -5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN -b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN -f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi -5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 -WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK -DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy -eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== ------END CERTIFICATE----- - IdenTrust Commercial Root CA 1 ============================== -----BEGIN CERTIFICATE----- @@ -2159,87 +2082,6 @@ F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== -----END CERTIFICATE----- -TrustCor RootCert CA-1 -====================== ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP -MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig -U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx -MjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu -YW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe -VHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy -dCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq -jQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4 -pQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0 -JEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h -gLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw -/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j -BBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5 -mDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf -ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C -qFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P -3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk= ------END CERTIFICATE----- - -TrustCor RootCert CA-2 -====================== ------BEGIN CERTIFICATE----- -MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w -DQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT -eXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0 -eTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy -MzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h -bWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U -cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0 -IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb -ZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk -RvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1 -oYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb -XUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1 -/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q -jxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP -eSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg -rKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh -8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU -2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h -Osh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp -kpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv -2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3 -S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw -PIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv -DDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU -RpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE -xdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX -RKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ ------END CERTIFICATE----- - -TrustCor ECA-1 -============== ------BEGIN CERTIFICATE----- -MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP -MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig -U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp -dHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw -N1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5 -MSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y -IENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR -MRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23 -xFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc -p0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+ -fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj -YzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL -f/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF -AAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u -/ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F -hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs -J5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC -jaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g== ------END CERTIFICATE----- - SSL.com Root Certification Authority RSA ======================================== -----BEGIN CERTIFICATE----- @@ -3345,3 +3187,186 @@ PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW -----END CERTIFICATE----- + +DigiCert TLS ECC P384 Root G5 +============================= +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURpZ2lDZXJ0IFRMUyBFQ0MgUDM4 +NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQg +Um9vdCBHNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1Tzvd +lHJS7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp0zVozptj +n4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICISB4CIfBFqMA4GA1UdDwEB +/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCJao1H5+z8blUD2Wds +Jk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQLgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIx +AJSdYsiJvRmEFOml+wG4DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +DigiCert TLS RSA4096 Root G5 +============================ +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQG +EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0 +MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2 +IFJvb3QgRzUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS8 +7IE+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG02C+JFvuU +AT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgpwgscONyfMXdcvyej/Ces +tyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZMpG2T6T867jp8nVid9E6P/DsjyG244gXa +zOvswzH016cpVIDPRFtMbzCe88zdH5RDnU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnV +DdXifBBiqmvwPXbzP6PosMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9q +TXeXAaDxZre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cdLvvy +z6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvXKyY//SovcfXWJL5/ +MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNeXoVPzthwiHvOAbWWl9fNff2C+MIk +wcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPLtgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4E +FgQUUTMc7TZArxfTJc1paPKvTiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7HPNtQOa27PShN +lnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLFO4uJ+DQtpBflF+aZfTCIITfN +MBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQREtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/ +u4cnYiWB39yhL/btp/96j1EuMPikAdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9G +OUrYU9DzLjtxpdRv/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh +47a+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilwMUc/dNAU +FvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WFqUITVuwhd4GTWgzqltlJ +yqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCKovfepEWFJqgejF0pW8hL2JpqA15w8oVP +bEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +Certainly Root R1 +================= +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE +BhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2VydGFpbmx5IFJvb3QgUjEwHhcN +MjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2Vy +dGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBANA21B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O +5MQTvqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbedaFySpvXl +8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b01C7jcvk2xusVtyWMOvwl +DbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGI +XsXwClTNSaa/ApzSRKft43jvRl5tcdF5cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkN +KPl6I7ENPT2a/Z2B7yyQwHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQ +AjeZjOVJ6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA2Cnb +rlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyHWyf5QBGenDPBt+U1 +VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMReiFPCyEQtkA6qyI6BJyLm4SGcprS +p6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTgqj8ljZ9EXME66C6ud0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAsz +HQNTVfSVcOQrPbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi1wrykXprOQ4v +MMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrdrRT90+7iIgXr0PK3aBLXWopB +GsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9ditaY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+ +gjwN/KUD+nsa2UUeYNrEjvn8K8l7lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgH +JBu6haEaBQmAupVjyTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7 +fpYnKx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLyyCwzk5Iw +x06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5nwXARPbv0+Em34yaXOp/S +X3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +Certainly Root E1 +================= +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQswCQYDVQQGEwJV +UzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBFMTAeFw0yMTA0 +MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlu +bHkxGjAYBgNVBAMTEUNlcnRhaW5seSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4 +fxzf7flHh4axpMCK+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9 +YBk2QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4hevIIgcwCgYIKoZIzj0E +AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 +rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +E-Tugra Global Root CA RSA v3 +============================= +-----BEGIN CERTIFICATE----- +MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQELBQAwgYAxCzAJ +BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAb +BgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290 +IENBIFJTQSB2MzAeFw0yMDAzMTgwOTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJU +UjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRF +LVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBSU0Eg +djMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J77gnJY9LTQ91ew6aEOErx +jYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscxuj7X/iWpKo429NEvx7epXTPcMHD4QGxL +sqYxYdE0PD0xesevxKenhOGXpOhL9hd87jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF +/YP9f4RtNGx/ardLAQO/rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8q +QedmCeFLl+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bGwzrw +bMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4znKS4iicvObpCdg6 +04nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBOM/J+JjKsBY04pOZ2PJ8QaQ5tndLB +eSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiM +bIedBi3x7+PmBvrFZhNb/FAHnnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbg +h3cXTJ2w2AmoDVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSytK7mLfcm1ap1 +LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAImocn+M684uGMQQ +gC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN4 +38o2Fi+CiJ+8EUdPdk3ILY7r3y18Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/q +ln0F7psTpURs+APQ3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3s +SdPkvmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn99t2HVhjY +sCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQmhty3QUBjYZgv6Rn7rWl +DdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YAVSgU7NbHEqIbZULpkejLPoeJVF3Zr52X +nGnnCv8PWniLYypMfUeUP95L6VPQMPHF9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFH +IK+WEj5jlB0E5y67hscMmoi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiX +YY60MGo8bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ +-----END CERTIFICATE----- + +E-Tugra Global Root CA ECC v3 +============================= +-----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV +BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB +IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP +MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 +Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 +w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 +Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ +zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO +PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W +Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 +-----END CERTIFICATE----- + +Security Communication RootCA3 +============================== +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw +IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD +b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw +CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE +AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r +hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE +NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2 +/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm +npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY +XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK +p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC +3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf +GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw +CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu +Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O +H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx +YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ +XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml ++LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn +KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9 +dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm +6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +Security Communication ECC RootCA1 +================================== +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD +VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t +dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL +MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV +BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo +5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW +BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK +BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L +snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e +N9k= +-----END CERTIFICATE----- From d001bba86bbeee07ff2ced2dc146603f71f76a53 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 21 Mar 2023 19:40:40 +0100 Subject: [PATCH 29/94] Finalize DNS via Proxy See #2328, original PR #2295 from @w4ntun . Formally testssl.sh returned an error when it wasn't not possible to determine IP addresses through DNS resolution, even if --proxy and --ip=proxy flags are set. The main function always tried to determine IP addresses via DNS and exits with a fatal error if it cannot do it. Although the client cannot get the IP, the proxy could, so the SSL/TLS analysis is still possible. This PR allows the analysis for an HTTP service via a proxy server and the DNS traffic can be sent directly or through the proxy using the flag --ip=proxy. ATTENTION: This may be a breaking change for those who don't have a local resolver. They now have to add --ip=proxy. In addition: * help() was amended to add --ip=proxy (was only in the ~i/doc dir before) * amending ~/doc dir to document it's better to add --nodns=min when there's no local resolver --- doc/testssl.1 | 4 ++-- doc/testssl.1.html | 4 ++-- doc/testssl.1.md | 5 ++--- testssl.sh | 13 ++++++++++--- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/doc/testssl.1 b/doc/testssl.1 index 030774a..b9fa266 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -88,7 +88,7 @@ A typical internal conversion to testssl\.sh file format from nmap's grep(p)able .P \fB\-\-mx \fR tests all MX records (STARTTLS on port 25) from high to low priority, one after the other\. .P -\fB\-\-ip \fR tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in \fB\fR\. IPv6 addresses need to be supplied in square brackets\. \fB\-\-ip=one\fR means: just test the first A record DNS returns (useful for multiple IPs)\. If \fB\-6\fR and \fB\-\-ip=one\fR was supplied an AAAA record will be picked if available\. The \fB\-\-ip\fR option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit \fB/etc/hosts\fR or \fB/c/Windows/System32/drivers/etc/hosts\fR\. \fB\-\-ip=proxy\fR tries a DNS resolution via proxy\. +\fB\-\-ip \fR tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in \fB\fR\. IPv6 addresses need to be supplied in square brackets\. \fB\-\-ip=one\fR means: just test the first A record DNS returns (useful for multiple IPs)\. If \fB\-6\fR and \fB\-\-ip=one\fR was supplied an AAAA record will be picked if available\. The \fB\-\-ip\fR option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit \fB/etc/hosts\fR or \fB/c/Windows/System32/drivers/etc/hosts\fR\. \fB\-\-ip=proxy\fR tries a DNS resolution via proxy\. \fB\-\-ip=proxy\fR plus \fB\-\-nodns=min\fR is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records\. .P \fB\-\-proxy :\fR does ANY check via the specified proxy\. \fB\-\-proxy=auto\fR inherits the proxy setting from the environment\. The hostname supplied will be resolved to the first A record\. In addition if you want lookups via proxy you can specify \fBDNS_VIA_PROXY=true\fR\. OCSP revocation checking (\fB\-S \-\-phone\-out\fR) is not supported by OpenSSL via proxy\. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed\. However if \fBIGN_OCSP_PROXY=true\fR has been supplied it will be tried directly\. Authentication to the proxy is not supported\. Proxying via IPv6 addresses is not possible, no HTTPS or SOCKS proxy is supported\. .P @@ -102,7 +102,7 @@ A typical internal conversion to testssl\.sh file format from nmap's grep(p)able .P \fB\-\-assuming\-http\fR testssl\.sh normally does upfront an application protocol detection\. In cases where HTTP cannot be automatically detected you may want to use this option\. It enforces testssl\.sh not to skip HTTP specific tests (HTTP header) and to run a browser based client simulation\. Please note that sometimes also the severity depends on the application protocol, e\.g\. SHA1 signed certificates, the lack of any SAN matches and some vulnerabilities will be punished harder when checking a web server as opposed to a mail server\. .P -\fB\-n, \-\-nodns \fR tells testssl\.sh which DNS lookups should be performed\. \fBmin\fR uses only forward DNS resolution (A and AAAA record or MX record) and skips CAA lookups and PTR records from the IP address back to a DNS name\. \fBnone\fR performs no DNS lookups at all\. For the latter you either have to supply the IP address as a target, to use \fB\-\-ip\fR or have the IP address in \fB/etc/hosts\fR\. The use of the switch is only useful if you either can't or are not willing to perform DNS lookups\. The latter can apply e\.g\. to some pentests\. In general this option could e\.g\. help you to avoid timeouts by DNS lookups\. \fBNODNS\fR is the environment variable for this\. +\fB\-n, \-\-nodns \fR tells testssl\.sh which DNS lookups should be performed\. \fBmin\fR uses only forward DNS resolution (A and AAAA record or MX record) and skips CAA lookups and PTR records from the IP address back to a DNS name\. \fBnone\fR performs no DNS lookups at all\. For the latter you either have to supply the IP address as a target, to use \fB\-\-ip\fR or have the IP address in \fB/etc/hosts\fR\. The use of the switch is only useful if you either can't or are not willing to perform DNS lookups\. The latter can apply e\.g\. to some pentests\. In general this option could e\.g\. help you to avoid timeouts by DNS lookups\. \fBNODNS\fR is the environment variable for this\. \fB\-\-nodns=min\fR plus \fB\-\-ip=proxy\fR is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records\. .P \fB\-\-sneaky\fR For HTTP header checks testssl\.sh uses normally the server friendly HTTP user agent \fBTLS tester from ${URL}\fR\. With this option your traces are less verbose and a Firefox user agent is being used\. Be aware that it doesn't hide your activities\. That is just not possible (environment preset via \fBSNEAKY=true\fR)\. .P diff --git a/doc/testssl.1.html b/doc/testssl.1.html index 21d35db..5b9c2cd 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -200,7 +200,7 @@ The same can be achieved by setting the environment variable WARNINGS--mx <domain|host> tests all MX records (STARTTLS on port 25) from high to low priority, one after the other.

    -

    --ip <ip> tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in <URI>. IPv6 addresses need to be supplied in square brackets. --ip=one means: just test the first A record DNS returns (useful for multiple IPs). If -6 and --ip=one was supplied an AAAA record will be picked if available. The --ip option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit /etc/hosts or /c/Windows/System32/drivers/etc/hosts. --ip=proxy tries a DNS resolution via proxy.

    +

    --ip <ip> tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in <URI>. IPv6 addresses need to be supplied in square brackets. --ip=one means: just test the first A record DNS returns (useful for multiple IPs). If -6 and --ip=one was supplied an AAAA record will be picked if available. The --ip option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit /etc/hosts or /c/Windows/System32/drivers/etc/hosts. --ip=proxy tries a DNS resolution via proxy. --ip=proxy tries a DNS resolution via proxy. --ip=proxy plus --nodns=min is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records.

    --proxy <host>:<port> does ANY check via the specified proxy. --proxy=auto inherits the proxy setting from the environment. The hostname supplied will be resolved to the first A record. In addition if you want lookups via proxy you can specify DNS_VIA_PROXY=true. OCSP revocation checking (-S --phone-out) is not supported by OpenSSL via proxy. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed. However if IGN_OCSP_PROXY=true has been supplied it will be tried directly. Authentication to the proxy is not supported. Proxying via IPv6 addresses is not possible, no HTTPS or SOCKS proxy is supported.

    @@ -217,7 +217,7 @@ The same can be achieved by setting the environment variable WARNINGS--assuming-http testssl.sh normally does upfront an application protocol detection. In cases where HTTP cannot be automatically detected you may want to use this option. It enforces testssl.sh not to skip HTTP specific tests (HTTP header) and to run a browser based client simulation. Please note that sometimes also the severity depends on the application protocol, e.g. SHA1 signed certificates, the lack of any SAN matches and some vulnerabilities will be punished harder when checking a web server as opposed to a mail server.

    -n, --nodns <min|none> tells testssl.sh which DNS lookups should be performed. min uses only forward DNS resolution (A and AAAA record or MX record) and skips CAA lookups and PTR records from the IP address back to a DNS name. none performs no DNS lookups at all. For the latter you either have to supply the IP address as a target, to use --ip or have the IP address -in /etc/hosts. The use of the switch is only useful if you either can't or are not willing to perform DNS lookups. The latter can apply e.g. to some pentests. In general this option could e.g. help you to avoid timeouts by DNS lookups. NODNS is the environment variable for this.

    +in /etc/hosts. The use of the switch is only useful if you either can't or are not willing to perform DNS lookups. The latter can apply e.g. to some pentests. In general this option could e.g. help you to avoid timeouts by DNS lookups. NODNS is the environment variable for this. --nodns=min plus --ip=proxy is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records.

    --sneaky For HTTP header checks testssl.sh uses normally the server friendly HTTP user agent TLS tester from ${URL}. With this option your traces are less verbose and a Firefox user agent is being used. Be aware that it doesn't hide your activities. That is just not possible (environment preset via SNEAKY=true).

    diff --git a/doc/testssl.1.md b/doc/testssl.1.md index 1795cc4..fcb90e9 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -122,7 +122,7 @@ The same can be achieved by setting the environment variable `WARNINGS`. `--mx ` tests all MX records (STARTTLS on port 25) from high to low priority, one after the other. -`--ip ` tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in ``. IPv6 addresses need to be supplied in square brackets. `--ip=one` means: just test the first A record DNS returns (useful for multiple IPs). If `-6` and `--ip=one` was supplied an AAAA record will be picked if available. The ``--ip`` option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit `/etc/hosts` or `/c/Windows/System32/drivers/etc/hosts`. `--ip=proxy` tries a DNS resolution via proxy. +`--ip ` tests either the supplied IPv4 or IPv6 address instead of resolving host(s) in ``. IPv6 addresses need to be supplied in square brackets. `--ip=one` means: just test the first A record DNS returns (useful for multiple IPs). If `-6` and `--ip=one` was supplied an AAAA record will be picked if available. The ``--ip`` option might be also useful if you want to resolve the supplied hostname to a different IP, similar as if you would edit `/etc/hosts` or `/c/Windows/System32/drivers/etc/hosts`. `--ip=proxy` tries a DNS resolution via proxy. `--ip=proxy` plus `--nodns=min` is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records. `--proxy :` does ANY check via the specified proxy. `--proxy=auto` inherits the proxy setting from the environment. The hostname supplied will be resolved to the first A record. In addition if you want lookups via proxy you can specify `DNS_VIA_PROXY=true`. OCSP revocation checking (`-S --phone-out`) is not supported by OpenSSL via proxy. As supplying a proxy is an indicator for port 80 and 443 outgoing being blocked in your network an OCSP revocation check won't be performed. However if `IGN_OCSP_PROXY=true` has been supplied it will be tried directly. Authentication to the proxy is not supported. Proxying via IPv6 addresses is not possible, no HTTPS or SOCKS proxy is supported. @@ -139,8 +139,7 @@ The same can be achieved by setting the environment variable `WARNINGS`. `--assuming-http` testssl.sh normally does upfront an application protocol detection. In cases where HTTP cannot be automatically detected you may want to use this option. It enforces testssl.sh not to skip HTTP specific tests (HTTP header) and to run a browser based client simulation. Please note that sometimes also the severity depends on the application protocol, e.g. SHA1 signed certificates, the lack of any SAN matches and some vulnerabilities will be punished harder when checking a web server as opposed to a mail server. -`-n, --nodns ` tells testssl.sh which DNS lookups should be performed. `min` uses only forward DNS resolution (A and AAAA record or MX record) and skips CAA lookups and PTR records from the IP address back to a DNS name. `none` performs no DNS lookups at all. For the latter you either have to supply the IP address as a target, to use `--ip` or have the IP address -in `/etc/hosts`. The use of the switch is only useful if you either can't or are not willing to perform DNS lookups. The latter can apply e.g. to some pentests. In general this option could e.g. help you to avoid timeouts by DNS lookups. `NODNS` is the environment variable for this. +`-n, --nodns ` tells testssl.sh which DNS lookups should be performed. `min` uses only forward DNS resolution (A and AAAA record or MX record) and skips CAA lookups and PTR records from the IP address back to a DNS name. `none` performs no DNS lookups at all. For the latter you either have to supply the IP address as a target, to use `--ip` or have the IP address in `/etc/hosts`. The use of the switch is only useful if you either can't or are not willing to perform DNS lookups. The latter can apply e.g. to some pentests. In general this option could e.g. help you to avoid timeouts by DNS lookups. `NODNS` is the environment variable for this. `--nodns=min` plus `--ip=proxy` is useful for situations with no local DNS as there'll be no DNS timeouts when trying to resolve CAA, TXT and MX records. `--sneaky` For HTTP header checks testssl.sh uses normally the server friendly HTTP user agent `TLS tester from ${URL}`. With this option your traces are less verbose and a Firefox user agent is being used. Be aware that it doesn't hide your activities. That is just not possible (environment preset via `SNEAKY=true`). diff --git a/testssl.sh b/testssl.sh index a432bdb..61f9312 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8828,7 +8828,7 @@ certificate_info() { local cn_finding trustfinding trustfinding_nosni local cnok="OK" local expfinding expok="OK" - local -i ret=0 + local -i ret=0 tmp=0 local json_postfix="" # string to place at the end of JSON IDs when there is more than one certificate local jsonID="" # string to place at beginning of JSON IDs local json_rating json_msg @@ -9686,6 +9686,8 @@ certificate_info() { caa="" while [[ -z "$caa" ]] && [[ -n "$caa_node" ]]; do caa="$(get_caa_rr_record $caa_node)" + tmp=${PIPESTATUS[@]} + [[ $DEBUG -ge 4 ]] && echo "get_caa_rr_record: $tmp" [[ $caa_node =~ '.'$ ]] || caa_node+="." caa_node=${caa_node#*.} done @@ -9707,6 +9709,9 @@ certificate_info() { elif [[ -n "$NODNS" ]]; then out "(instructed to minimize DNS queries)" fileout "${jsonID}${json_postfix}" "INFO" "check skipped as instructed" + elif "$DNS_VIA_PROXY"; then + out "(instructed to use the proxy for DNS only)" + fileout "${jsonID}${json_postfix}" "INFO" "check skipped as instructed (proxy)" else pr_svrty_low "not offered" fileout "${jsonID}${json_postfix}" "LOW" "--" @@ -20308,7 +20313,8 @@ tuning / connect options (most also can be preset via environment variables): --proxy (experimental) proxy connects via , auto: values from \$env (\$http(s)_proxy) -6 also use IPv6. Works only with supporting OpenSSL version and IPv6 connectivity --ip a) tests the supplied v4 or v6 address instead of resolving host(s) in URI - b) arg "one" means: just test the first DNS returns (useful for multiple IPs) + b) "one" means: just test the first DNS returns (useful for multiple IPs) + c) "proxy" means: dns resolution via proxy. Needed when host has no DNS. -n, --nodns if "none": do not try any DNS lookups, "min" queries A, AAAA and MX records --sneaky leave less traces in target logs: user agent, referer --user-agent set a custom user agent instead of the standard user agent @@ -21026,7 +21032,8 @@ get_caa_rr_record() { "$HAS_DIG_NOIDNOUT" && noidnout="+noidnout" - [[ -n "$NODNS" ]] && return 0 # if minimum DNS lookup was instructed, leave here + [[ -n "$NODNS" ]] && return 2 # if minimum DNS lookup was instructed, leave here + # if there's a type257 record there are two output formats here, mostly depending on age of distribution # roughly that's the difference between text and binary format # 1) 'google.com has CAA record 0 issue "symantec.com"' From 1392987f01b748021cda4e98cbaf8e151c2f9a32 Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Wed, 22 Mar 2023 21:18:36 +1300 Subject: [PATCH 30/94] refactor: Change base image from `alpine:3.17` to `opensuse/leap:15.4` --- Dockerfile | 91 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 92a42c8..a49f3fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,87 @@ -FROM alpine:3.17 +# syntax=docker.io/docker/dockerfile:1 +# HereDoc (EOF) feature (avoids needing `&& \`) requires BuildKit: +# https://docs.docker.com/engine/reference/builder/#here-documents +ARG LEAP_VERSION=15.4 +ARG CACHE_ZYPPER=/tmp/cache/zypper +ARG INSTALL_ROOT=/rootfs -RUN apk update && \ - apk upgrade && \ - apk add bash procps drill git coreutils libidn curl socat openssl xxd && \ - rm -rf /var/cache/apk/* && \ - adduser -D -s /bin/bash testssl && \ - ln -s /home/testssl/testssl.sh /usr/local/bin/ +FROM opensuse/leap:${LEAP_VERSION} as builder +ARG CACHE_ZYPPER +ARG INSTALL_ROOT +# --mount is only necessary for persisting the zypper cache on the build host, +# Paired with --cache-dir below, RUN layer invalidation does not clear this cache. +# Not useful for CI, only local builds that retain the storage. +RUN --mount=type=cache,target="${CACHE_ZYPPER}",sharing=locked < Date: Wed, 22 Mar 2023 20:58:47 +1300 Subject: [PATCH 31/94] fix: Manually create `testssl` user and home BusyBox `adduser` was reading config from `/etc` that unnecessarily populates the home folder with various dot files. Alternative approach is to create the user and home folder manually. This avoids some extra files like the `-` suffixed backup copies from `adduser`. --- Dockerfile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index a49f3fe..8820cdc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -70,17 +70,17 @@ EOF FROM scratch ARG INSTALL_ROOT COPY --link --from=builder ${INSTALL_ROOT} / +RUN <> /etc/passwd + echo 'testssl:x:1000:' >> /etc/group + echo 'testssl:!::0:::::' >> /etc/shadow -# zypper package `busybox-adduser` fails to install with `--installroot`, -# while the `shadow` package is too heavy just to add a user. -# -# Temporarily bind mount the `/bin` dir from another image that already -# has the `adduser` command, and it'll update `/etc/{group,passwd,shadow}` for us: -# Absolute path provided as some base images PATH would use those binaries instead, -# `adduser` varies in supported args, so this should avoid any surprises: -RUN --mount=type=bind,from=busybox:latest,source=/bin,target=/bin < Date: Wed, 22 Mar 2023 21:16:50 +1300 Subject: [PATCH 32/94] fix: `WORKDIR` before `adduser` avoids surprises The additions from `adduser` reading `/etc` does not appear to apply if the directory already exists, and permissions (including SGID) are adjusted properly for the home dir. This mean the excess backup copies in `/etc` are introduced again however. --- Dockerfile | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8820cdc..d5749a9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -70,24 +70,14 @@ EOF FROM scratch ARG INSTALL_ROOT COPY --link --from=builder ${INSTALL_ROOT} / -RUN <> /etc/passwd - echo 'testssl:x:1000:' >> /etc/group - echo 'testssl:!::0:::::' >> /etc/shadow - - # Create user home with SGID set: - install --mode 2755 --owner testssl --group testssl --directory /home/testssl - - # Add relative symlink to point to content that will COPY later: - ln -sr /home/testssl/testssl.sh /usr/local/bin/ +WORKDIR /home/testssl +RUN --mount=type=bind,from=busybox:latest,source=/bin,target=/bin < Date: Wed, 22 Mar 2023 21:31:34 +1300 Subject: [PATCH 33/94] chore: Revise `Dockerfile` - Removing bulk of the noise from inline documentation. - Packages bundled into single line like previous the Alpine version had. - `CACHE_ZYPPER` is only used as an `ARG` in the `builder` stage. - `zypper clean` wasn't able to clear anything from the install root, other than the `CACHE_ZYPPER` mount. --- Dockerfile | 47 ++++++++--------------------------------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/Dockerfile b/Dockerfile index d5749a9..c041ccb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,66 +1,35 @@ # syntax=docker.io/docker/dockerfile:1 -# HereDoc (EOF) feature (avoids needing `&& \`) requires BuildKit: -# https://docs.docker.com/engine/reference/builder/#here-documents + ARG LEAP_VERSION=15.4 -ARG CACHE_ZYPPER=/tmp/cache/zypper ARG INSTALL_ROOT=/rootfs FROM opensuse/leap:${LEAP_VERSION} as builder -ARG CACHE_ZYPPER +ARG CACHE_ZYPPER=/tmp/cache/zypper ARG INSTALL_ROOT # --mount is only necessary for persisting the zypper cache on the build host, # Paired with --cache-dir below, RUN layer invalidation does not clear this cache. # Not useful for CI, only local builds that retain the storage. RUN --mount=type=cache,target="${CACHE_ZYPPER}",sharing=locked < Date: Wed, 22 Mar 2023 22:13:18 +1300 Subject: [PATCH 34/94] refactor: Support syntax without BuildKit features These have been available via opt-in prior to v23 of Docker Engine with `DOCKER_BUILDKIT=1` ENV as a prefix to running `docker build`, however it's been requested to avoid the syntax. No HereDoc (multi-line RUN with EOF marker) or `RUN --mount` available. This makes the `busybox` approach a hassle, so I've brought back the explicit creation of user and home dir. Without the cache mounts, bring back `zypper clean`. It's not doing much as the `--cache-dir` is still set, but should reduce disk space for the `builder` layer. Local builds will be slower as a result when this layer is invalidated. AFAIK, this also makes it tricky to use the `ZYPPER_OPTIONS`? So no longer DRY. --- Dockerfile | 54 ++++++++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/Dockerfile b/Dockerfile index c041ccb..c4af7ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,44 +6,34 @@ ARG INSTALL_ROOT=/rootfs FROM opensuse/leap:${LEAP_VERSION} as builder ARG CACHE_ZYPPER=/tmp/cache/zypper ARG INSTALL_ROOT -# --mount is only necessary for persisting the zypper cache on the build host, -# Paired with --cache-dir below, RUN layer invalidation does not clear this cache. -# Not useful for CI, only local builds that retain the storage. -RUN --mount=type=cache,target="${CACHE_ZYPPER}",sharing=locked <> /etc/passwd \ + && echo 'testssl:x:1000:' >> /etc/group \ + && echo 'testssl:!::0:::::' >> /etc/shadow \ + && install --mode 2755 --owner testssl --group testssl --directory /home/testssl \ + && ln -s /home/testssl/testssl.sh /usr/local/bin/ # Copy over build context (after filtered by .dockerignore): bin/ etc/ testssl.sh COPY --chown=testssl:testssl . /home/testssl/ From 6af0a801ec4f4c5cf22794fb734422a6c3997300 Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Wed, 22 Mar 2023 22:56:59 +1300 Subject: [PATCH 35/94] chore: Bring back `ZYPPER_OPTIONS` --- Dockerfile | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index c4af7ce..85dfc32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,21 +6,18 @@ ARG INSTALL_ROOT=/rootfs FROM opensuse/leap:${LEAP_VERSION} as builder ARG CACHE_ZYPPER=/tmp/cache/zypper ARG INSTALL_ROOT -# Usually you could source this from /etc/os-release -# Might not always match the image tag: -ARG VERSION_ID=15.4 -RUN zypper --releasever "${VERSION_ID}" --installroot "${INSTALL_ROOT}" --cache-dir "${CACHE_ZYPPER}" \ - --gpg-auto-import-keys refresh \ - && zypper --releasever "${VERSION_ID}" --installroot "${INSTALL_ROOT}" --cache-dir "${CACHE_ZYPPER}" \ - --non-interactive install --download-in-advance --no-recommends \ +# /etc/os-release provides $VERSION_ID +RUN source /etc/os-release \ + && export ZYPPER_OPTIONS=( --releasever "${VERSION_ID}" --installroot "${INSTALL_ROOT}" --cache-dir "${CACHE_ZYPPER}" ) \ + && zypper "${ZYPPER_OPTIONS[@]}" --gpg-auto-import-keys refresh \ + && zypper "${ZYPPER_OPTIONS[@]}" --non-interactive install --download-in-advance --no-recommends \ bash procps grep gawk sed coreutils busybox-util-linux busybox-vi ldns libidn2-0 socat openssl curl \ - && zypper --releasever "${VERSION_ID}" --installroot "${INSTALL_ROOT}" --cache-dir "${CACHE_ZYPPER}" \ - clean --all + && zypper "${ZYPPER_OPTIONS[@]}" clean --all ## Cleanup (reclaim approx 13 MiB): # None of this content should be relevant to the container: RUN rm -r "${INSTALL_ROOT}/usr/share/"{licenses,man,locale,doc,help,info} # Functionality that the container doesn't need: -RUN rm "${INSTALL_ROOT}/usr/share/misc/termcap" \ +RUN rm "${INSTALL_ROOT}/usr/share/misc/termcap" \ && rm -r "${INSTALL_ROOT}/usr/lib/sysimage/rpm" From cf0c1c1f5fb0792bbfa1b42afbfeaf622b82b54f Mon Sep 17 00:00:00 2001 From: Odinmylord Date: Wed, 22 Mar 2023 23:14:56 +0100 Subject: [PATCH 36/94] Added more details to the SignatureAlgorithms --- testssl.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/testssl.sh b/testssl.sh index b739044..57527eb 100755 --- a/testssl.sh +++ b/testssl.sh @@ -10380,7 +10380,7 @@ run_fs() { local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") local -a supported_curve local -a sigalgs_hex=("01,01" "01,02" "01,03" "02,01" "02,02" "02,03" "03,01" "03,02" "03,03" "04,01" "04,02" "04,03" "04,20" "05,01" "05,02" "05,03" "05,20" "06,01" "06,02" "06,03" "06,20" "07,08" "08,04" "08,05" "08,06" "08,07" "08,08" "08,09" "08,0a" "08,0b" "08,1a" "08,1b" "08,1c") - local -a sigalgs_strings=("RSA+MD5" "DSA+MD5" "ECDSA+MD5" "RSA+SHA1" "DSA+SHA1" "ECDSA+SHA1" "RSA+SHA224" "DSA+SHA224" "ECDSA+SHA224" "RSA+SHA256" "DSA+SHA256" "ECDSA+SHA256" "RSA+SHA256" "RSA+SHA384" "DSA+SHA384" "ECDSA+SHA384" "RSA+SHA384" "RSA+SHA512" "DSA+SHA512" "ECDSA+SHA512" "RSA+SHA512" "SM2+SM3" "RSA-PSS+SHA256" "RSA-PSS+SHA384" "RSA-PSS+SHA512" "Ed25519" "Ed448" "RSA-PSS+SHA256" "RSA-PSS+SHA384" "RSA-PSS+SHA512" "ECDSA+SHA256" "ECDSA+SHA384" "ECDSA+SHA512") + local -a sigalgs_strings=("RSA+MD5" "DSA+MD5" "ECDSA+MD5" "RSA+SHA1" "DSA+SHA1" "ECDSA+SHA1" "RSA+SHA224" "DSA+SHA224" "ECDSA+SHA224" "RSA+SHA256" "DSA+SHA256" "ECDSA+SHA256" "RSA+SHA256" "RSA+SHA384" "DSA+SHA384" "ECDSA+SHA384" "RSA+SHA384" "RSA+SHA512" "DSA+SHA512" "ECDSA+SHA512" "RSA+SHA512" "SM2+SM3" "RSA-PSS-RSAE+SHA256" "RSA-PSS-RSAE+SHA384" "RSA-PSS-RSAE+SHA512" "Ed25519" "Ed448" "RSA-PSS-PSS+SHA256" "RSA-PSS-PSS+SHA384" "RSA-PSS-PSS+SHA512" "ECDSA+SHA256" "ECDSA+SHA384" "ECDSA+SHA512") local -a tls13_supported_sigalgs=("false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false") local -a tls12_supported_sigalgs=("false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false") local rsa_cipher="" ecdsa_cipher="" dss_cipher="" @@ -15027,14 +15027,14 @@ parse_tls_serverhello() { if [[ 0x$peering_signing_digest -eq 8 ]] && \ [[ 0x$peer_signature_type -ge 4 ]] && [[ 0x$peer_signature_type -le 11 ]]; then case $peer_signature_type in - 04) peering_signing_digest="SHA256"; peer_signature_type="RSA-PSS" ;; - 05) peering_signing_digest="SHA384"; peer_signature_type="RSA-PSS" ;; - 06) peering_signing_digest="SHA512"; peer_signature_type="RSA-PSS" ;; + 04) peering_signing_digest="SHA256"; peer_signature_type="RSA-PSS-RSAE" ;; + 05) peering_signing_digest="SHA384"; peer_signature_type="RSA-PSS-RSAE" ;; + 06) peering_signing_digest="SHA512"; peer_signature_type="RSA-PSS-RSAE" ;; 07) peering_signing_digest=""; peer_signature_type="Ed25519" ;; 08) peering_signing_digest=""; peer_signature_type="Ed448" ;; - 09) peering_signing_digest="SHA256"; peer_signature_type="RSA-PSS" ;; - 0A) peering_signing_digest="SHA384"; peer_signature_type="RSA-PSS" ;; - 0B) peering_signing_digest="SHA512"; peer_signature_type="RSA-PSS" ;; + 09) peering_signing_digest="SHA256"; peer_signature_type="RSA-PSS-PSS" ;; + 0A) peering_signing_digest="SHA384"; peer_signature_type="RSA-PSS-PSS" ;; + 0B) peering_signing_digest="SHA512"; peer_signature_type="RSA-PSS-PSS" ;; esac if [[ -n "$peering_signing_digest" ]]; then echo "Peer signing digest: $peering_signing_digest" >> $TMPFILE From 035996cc4450b21ba4fb978eed7bd12fd1d766cf Mon Sep 17 00:00:00 2001 From: Odinmylord Date: Thu, 23 Mar 2023 00:14:15 +0100 Subject: [PATCH 37/94] updated default_testssl.csvfile with new RSA-PSS --- t/baseline_data/default_testssl.csvfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/baseline_data/default_testssl.csvfile b/t/baseline_data/default_testssl.csvfile index 4a0866b..28118ba 100644 --- a/t/baseline_data/default_testssl.csvfile +++ b/t/baseline_data/default_testssl.csvfile @@ -66,8 +66,8 @@ "FS_ciphers","testssl.sh/81.169.166.184","443","INFO","TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-RSA-AES256-SHA DHE-RSA-CAMELLIA256-SHA TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-RSA-AES128-SHA DHE-RSA-CAMELLIA128-SHA","","" "FS_ECDHE_curves","testssl.sh/81.169.166.184","443","OK","prime256v1 secp384r1 secp521r1 X25519 X448","","" "DH_groups","testssl.sh/81.169.166.184","443","OK","Unknown DH group (2048 bits)","","" -"FS_TLS12_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS+SHA256 RSA-PSS+SHA384 RSA-PSS+SHA512 RSA+SHA256 RSA+SHA384 RSA+SHA512 RSA+SHA224","","" -"FS_TLS13_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS+SHA256 RSA-PSS+SHA384 RSA-PSS+SHA512","","" +"FS_TLS12_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512 RSA+SHA256 RSA+SHA384 RSA+SHA512 RSA+SHA224","","" +"FS_TLS13_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512","","" "HTTP_status_code","testssl.sh/81.169.166.184","443","INFO","200 OK ('/')","","" "HTTP_clock_skew","testssl.sh/81.169.166.184","443","INFO","0 seconds from localtime","","" "HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1654006271","","" From 48a597e19d42167aeeb4eb886c8365988d222ed6 Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 23 Mar 2023 09:11:14 +0100 Subject: [PATCH 38/94] don't forget the kudos ;-) --- CHANGELOG.md | 1 + CREDITS.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3324bb2..e485992 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ * Client simulation runs in wide mode which is even better readable * Added --reqheader to support custom headers in HTTP requests * Test for support for RFC 8879 certificate compression +* Dockerfiles refactored to be multistaged: performance gain+address bugs/inconsistencies ### Features implemented / improvements in 3.0 diff --git a/CREDITS.md b/CREDITS.md index 126e0a4..bb6666c 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -84,6 +84,9 @@ Full contribution, see git log. * Hubert Kario - helped with avoiding accidental TCP fragmentation +* Brandon Kinney + - refactored multistage Dockerfiles: performance gain+address bugs/inconsistencies + * Magnus Larsen - SSL Labs Rating From bad5dedf4262754dc2b2247607498079c8466679 Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 23 Mar 2023 14:22:05 +0100 Subject: [PATCH 39/94] correcting Brennan's name --- CREDITS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CREDITS.md b/CREDITS.md index bb6666c..9c73cf1 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -84,7 +84,7 @@ Full contribution, see git log. * Hubert Kario - helped with avoiding accidental TCP fragmentation -* Brandon Kinney +* Brennan Kinney - refactored multistage Dockerfiles: performance gain+address bugs/inconsistencies * Magnus Larsen From 90aa86ce6bbcb42148beb588e0841acf9d4a7f71 Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 23 Mar 2023 14:45:51 +0100 Subject: [PATCH 40/94] add another contributor and change (not related to this PR but it'll be forgotten otherwise) --- CREDITS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CREDITS.md b/CREDITS.md index 9c73cf1..56c3a4b 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -176,6 +176,9 @@ Full contribution, see git log. * @nvsofts (NV) - LibreSSL patch for GOST +* @w4ntun + - fixed DNS via proxy + Probably more I forgot to mention which did give me feedback, bug reports and helped one way or another. From 91f3d9716bfcdbb135bf27c1013d1fb83b91eea9 Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 23 Mar 2023 15:05:15 +0100 Subject: [PATCH 41/94] amending previous commit --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e485992..d21d7c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ * Client simulation runs in wide mode which is even better readable * Added --reqheader to support custom headers in HTTP requests * Test for support for RFC 8879 certificate compression +* Doesn't hang anymore when there's no local resolver * Dockerfiles refactored to be multistaged: performance gain+address bugs/inconsistencies ### Features implemented / improvements in 3.0 From 5002dd23b18bf6d8e701defad0047eee65d48e5f Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 27 Mar 2023 18:09:54 -0700 Subject: [PATCH 42/94] Add support for brainpool curves with TLS 1.3 This commit adds support for the curves brainpoolP256r1tls13, brainpoolP384r1tls13, and brainpoolP512r1tls13. --- etc/curves.txt | 5 +++- etc/tls_data.txt | 31 ++++++++++++++++++++--- testssl.sh | 44 +++++++++++++++++++-------------- utils/update_client_sim_data.pl | 6 +++++ 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/etc/curves.txt b/etc/curves.txt index fe7d0b8..cbb7595 100644 --- a/etc/curves.txt +++ b/etc/curves.txt @@ -28,4 +28,7 @@ 27, brainpoolP384r1, 28, brainpoolP512r1, 29, curve25519, -30, curve448 +30, curve448, +31, brainpoolP256r1tls13, +32, brainpoolP384r1tls13, +33, brainpoolP512r1tls13 diff --git a/etc/tls_data.txt b/etc/tls_data.txt index e987361..5fc5b7c 100644 --- a/etc/tls_data.txt +++ b/etc/tls_data.txt @@ -124,8 +124,29 @@ MC4CAQAwBQYDK2VuBCIEIDhCPq41ufKeHdfVAp6KeS7qo8E43pd+ee+npH0sOqxL MEYCAQAwBQYDK2VvBDoEONDoNojolTC5A5LwJmEfj/NqVrkG2PsagQ0IxZJcwyhC CrAkCbaEfSIdjRVr2ODIC8ByiHjIzqDu -----END PRIVATE KEY----- -" "1f" - "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "2a" "2b" "2c" "2d" "2e" "2f" +" +"-----BEGIN PRIVATE KEY----- +MIGIAgEAMBQGByqGSM49AgEGCSskAwMCCAEBBwRtMGsCAQEEID/S1T+6vhaiWJT6 +2qbAFBlBi7Bd2fe6eRJlw6I2zm0eoUQDQgAEdk7i/WWNR873mVlffUL/XYPW04fd +eVf2KlfRUi8aoINfkxsw/yVVOuVfT8GivrEs1kT2iiy0Z+gyXDrYiSqP1w== +-----END PRIVATE KEY----- +" +"-----BEGIN PRIVATE KEY----- +MIG6AgEAMBQGByqGSM49AgEGCSskAwMCCAEBCwSBnjCBmwIBAQQwbV1IckTIgFs6 +YOOLLFeLmc6BLjqHUbLHLwZjI8TKNMIzYahhc9n5wgSyn+Psu3NWoWQDYgAEA/NN +eFinukOQpX+Alpccd0NnRL59YdYmhI5VSdQECDyUym4hH2L7uHXdOZaC/qxvPQxz +QDY3nqerDkwIB+rFj1qWOKzqyZt2KlVk2jE3Omsrhuo92Ai94X0LyW2SMRyh +-----END PRIVATE KEY----- +" +"-----BEGIN PRIVATE KEY----- +MIHsAgEAMBQGByqGSM49AgEGCSskAwMCCAEBDQSB0DCBzQIBAQRAmfrMGcK0wj3D +QNMCwBQaQHY03cTJuQbjjFr1Mrqn73ARDxUel6xdklEWx3SE9gbG0KVGnCx/nslG +xS6XqyNhhqGBhQOBggAEDjRvgELV732xXBsz5NJuirkmran6haJy2Phqqc4qPROm +0iUjpSOrq0DV5MUE/0HhvzvOSqkSWr7nAefO1bovml+Fo5YT+KUsZJMYK7DlDtCb +79ZjkNvTbrsL9GVNvOmyUJv+PyxG1Zn6OsIxck747cJ/IGeOv7hcA+/J728TfWk= +-----END PRIVATE KEY----- +" + "22" "23" "24" "25" "26" "27" "28" "29" "2a" "2b" "2c" "2d" "2e" "2f" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "3a" "3b" "3c" "3d" "3e" "3f" "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "4a" "4b" "4c" "4d" "4e" "4f" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "5a" "5b" "5c" "5d" "5e" "5f" @@ -296,8 +317,10 @@ readonly -a TLS13_PUBLIC_KEY_SHARES=( "1a" "1b" "1c" "00,1d,00,20,4d,fa,57,44,b7,f7,48,b8,95,77,5a,c1,ff,86,bf,ae,f7,3a,33,69,54,de,6a,f5,2e,89,84,6c,f2,d8,b2,43" "00,1e,00,38,6d,6d,67,a7,4e,3d,45,dd,ec,7e,a0,70,88,56,54,d8,c5,7c,4d,f3,8f,8b,f8,f2,14,06,1b,a0,4f,f7,ad,6b,3f,3a,90,42,41,8e,74,28,32,4a,a7,50,4a,7a,8e,42,55,eb,94,96,de,83,37,d6" - "1f" - "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "2a" "2b" "2c" "2d" "2e" "2f" + "00,1f,00,41,04,76,4e,e2,fd,65,8d,47,ce,f7,99,59,5f,7d,42,ff,5d,83,d6,d3,87,dd,79,57,f6,2a,57,d1,52,2f,1a,a0,83,5f,93,1b,30,ff,25,55,3a,e5,5f,4f,c1,a2,be,b1,2c,d6,44,f6,8a,2c,b4,67,e8,32,5c,3a,d8,89,2a,8f,d7" + "00,20,00,61,04,03,f3,4d,78,58,a7,ba,43,90,a5,7f,80,96,97,1c,77,43,67,44,be,7d,61,d6,26,84,8e,55,49,d4,04,08,3c,94,ca,6e,21,1f,62,fb,b8,75,dd,39,96,82,fe,ac,6f,3d,0c,73,40,36,37,9e,a7,ab,0e,4c,08,07,ea,c5,8f,5a,96,38,ac,ea,c9,9b,76,2a,55,64,da,31,37,3a,6b,2b,86,ea,3d,d8,08,bd,e1,7d,0b,c9,6d,92,31,1c,a1" + "00,21,00,81,04,0e,34,6f,80,42,d5,ef,7d,b1,5c,1b,33,e4,d2,6e,8a,b9,26,ad,a9,fa,85,a2,72,d8,f8,6a,a9,ce,2a,3d,13,a6,d2,25,23,a5,23,ab,ab,40,d5,e4,c5,04,ff,41,e1,bf,3b,ce,4a,a9,12,5a,be,e7,01,e7,ce,d5,ba,2f,9a,5f,85,a3,96,13,f8,a5,2c,64,93,18,2b,b0,e5,0e,d0,9b,ef,d6,63,90,db,d3,6e,bb,0b,f4,65,4d,bc,e9,b2,50,9b,fe,3f,2c,46,d5,99,fa,3a,c2,31,72,4e,f8,ed,c2,7f,20,67,8e,bf,b8,5c,03,ef,c9,ef,6f,13,7d,69" + "22" "23" "24" "25" "26" "27" "28" "29" "2a" "2b" "2c" "2d" "2e" "2f" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "3a" "3b" "3c" "3d" "3e" "3f" "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" "4a" "4b" "4c" "4d" "4e" "4f" "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" "5a" "5b" "5c" "5d" "5e" "5f" diff --git a/testssl.sh b/testssl.sh index 4e0115c..e68c75b 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6396,9 +6396,9 @@ pr_ecdh_curve_quality() { "prime256v1") bits=256 ;; "secp384r1") bits=384 ;; "secp521r1") bits=521 ;; - "brainpoolP256r1") bits=256 ;; - "brainpoolP384r1") bits=384 ;; - "brainpoolP512r1") bits=512 ;; + "brainpoolP256r1"*) bits=256 ;; + "brainpoolP384r1"*) bits=384 ;; + "brainpoolP512r1"*) bits=512 ;; "X25519") bits=253 ;; "X448") bits=448 ;; esac @@ -10374,13 +10374,13 @@ run_fs() { local fs_cipher_list="DHE-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA:DHE-DSS-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA:DHE-DSS-SEED-SHA:DHE-RSA-AES128-CCM8:DHE-RSA-AES128-CCM:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-CHACHA20-POLY1305-OLD:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-SEED-SHA:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305-OLD:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-RSA-CHACHA20-POLY1305-OLD:ECDHE-RSA-CHACHA20-POLY1305" local fs_hex_cipher_list="" ciphers_to_test tls13_ciphers_to_test local ecdhe_cipher_list="" tls13_cipher_list="" ecdhe_cipher_list_hex="" ffdhe_cipher_list_hex="" - local curves_hex=("00,01" "00,02" "00,03" "00,04" "00,05" "00,06" "00,07" "00,08" "00,09" "00,0a" "00,0b" "00,0c" "00,0d" "00,0e" "00,0f" "00,10" "00,11" "00,12" "00,13" "00,14" "00,15" "00,16" "00,17" "00,18" "00,19" "00,1a" "00,1b" "00,1c" "00,1d" "00,1e") - local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448") - local -a curves_ossl_output=("K-163" "sect163r1" "B-163" "sect193r1" "sect193r2" "K-233" "B-233" "sect239k1" "K-283" "B-283" "K-409" "B-409" "K-571" "B-571" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "P-192" "secp224k1" "P-224" "secp256k1" "P-256" "P-384" "P-521" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448") - local -ai curves_bits=(163 162 163 193 193 232 233 238 281 282 407 409 570 570 161 161 161 192 192 225 224 256 256 384 521 256 384 512 253 448) + local curves_hex=("00,01" "00,02" "00,03" "00,04" "00,05" "00,06" "00,07" "00,08" "00,09" "00,0a" "00,0b" "00,0c" "00,0d" "00,0e" "00,0f" "00,10" "00,11" "00,12" "00,13" "00,14" "00,15" "00,16" "00,17" "00,18" "00,19" "00,1a" "00,1b" "00,1c" "00,1d" "00,1e" "00,1f" "00,20" "00,21") + local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13") + local -a curves_ossl_output=("K-163" "sect163r1" "B-163" "sect193r1" "sect193r2" "K-233" "B-233" "sect239k1" "K-283" "B-283" "K-409" "B-409" "K-571" "B-571" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "P-192" "secp224k1" "P-224" "secp256k1" "P-256" "P-384" "P-521" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13") + local -ai curves_bits=(163 162 163 193 193 232 233 238 281 282 407 409 570 570 161 161 161 192 192 225 224 256 256 384 521 256 384 512 253 448 256 384 512) # Many curves have been deprecated, and RFC 8446, Appendix B.3.1.4, states # that these curves MUST NOT be offered in a TLS 1.3 ClientHello. - local -a curves_deprecated=("true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "false" "false" "false" "true" "true" "true" "false" "false") + local -a curves_deprecated=("true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "false" "false" "false" "true" "true" "true" "false" "false" "false" "false" "false") local -a ffdhe_groups_hex=("01,00" "01,01" "01,02" "01,03" "01,04") local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") local -a supported_curve @@ -10740,6 +10740,9 @@ run_fs() { if [[ "$curve_found" == ECDH ]]; then curve_found="${temp#*, }" curve_found="${curve_found%%,*}" + if "$HAS_TLS13" && [[ ! "$proto" == "-no_tls1_3" ]] && [[ "$curve_found" == brainpoolP[235][581][642]r1 ]]; then + [[ "$(get_protocol "$TMPFILE")" == TLSv1.3 ]] && curve_found+="tls13" + fi fi for (( i=low; i < high; i++ )); do if ! "${supported_curve[i]}"; then @@ -14403,6 +14406,9 @@ parse_tls_serverhello() { 25) dh_bits=521 ; named_curve_str="P-521" ; named_curve_oid="06052b81040023" ;; 29) dh_bits=253 ; named_curve_str="X25519" ;; 30) dh_bits=448 ; named_curve_str="X448" ;; + 31) dh_bits=256 ; named_curve_str="brainpoolP256r1tls13" ; named_curve_oid="06092B2403030208010107" ;; + 32) dh_bits=384 ; named_curve_str="brainpoolP384r1tls13" ; named_curve_oid="06092B240303020801010B" ;; + 33) dh_bits=512 ; named_curve_str="brainpoolP512r1tls13" ; named_curve_oid="06092B240303020801010D" ;; 256) dh_bits=2048 ; named_curve_str="ffdhe2048" ;; 257) dh_bits=3072 ; named_curve_str="ffdhe3072" ;; 258) dh_bits=4096 ; named_curve_str="ffdhe4096" ;; @@ -15430,8 +15436,8 @@ prepare_tls_clienthello() { if [[ ! "$process_full" =~ all ]] || { "$HAS_X25519" && "$HAS_X448"; }; then extension_supported_groups=" 00,0a, # Type: Supported Groups, see RFC 8446 - 00,10, 00,0e, # lengths - 00,1d, 00,17, 00,1e, 00,18, 00,19, + 00,16, 00,14, # lengths + 00,1d, 00,17, 00,1e, 00,18, 00,19, 00,1f, 00,20, 00,21, 01,00, 01,01" # OpenSSL prior to 1.1.1 does not support X448, so list it as the least # preferred option if the response needs to be decrypted, and do not @@ -15439,14 +15445,14 @@ prepare_tls_clienthello() { elif "$HAS_X25519" && [[ "$process_full" == all+ ]]; then extension_supported_groups=" 00,0a, # Type: Supported Groups, see RFC 8446 - 00,0e, 00,0c, # lengths - 00,1d, 00,17, 00,18, 00,19, + 00,14, 00,12, # lengths + 00,1d, 00,17, 00,18, 00,19, 00,1f, 00,20, 00,21, 01,00, 01,01" elif "$HAS_X25519"; then extension_supported_groups=" 00,0a, # Type: Supported Groups, see RFC 8446 - 00,10, 00,0e, # lengths - 00,1d, 00,17, 00,18, 00,19, + 00,16, 00,14, # lengths + 00,1d, 00,17, 00,18, 00,19, 00,1f, 00,20, 00,21, 01,00, 01,01, 00,1e" # OpenSSL prior to 1.1.0 does not support either X25519 or X448, # so list them as the least referred options if the response @@ -15455,14 +15461,14 @@ prepare_tls_clienthello() { elif [[ "$process_full" == all+ ]]; then extension_supported_groups=" 00,0a, # Type: Supported Groups, see RFC 8446 - 00,0c, 00,0a, # lengths - 00,17, 00,18, 00,19, + 00,12, 00,10, # lengths + 00,17, 00,18, 00,19, 00,1f, 00,20, 00,21, 01,00, 01,01" else extension_supported_groups=" 00,0a, # Type: Supported Groups, see RFC 8446 - 00,10, 00,0e, # lengths - 00,17, 00,18, 00,19, + 00,16, 00,14, # lengths + 00,17, 00,18, 00,19, 00,1f, 00,20, 00,21, 01,00, 01,01, 00,1d, 00,1e" fi @@ -19911,7 +19917,7 @@ find_openssl_binary() { local openssl_location cwd="" local ossl_wo_dev_info local curve - local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448" "ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") + local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13" "ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") # 0. check environment variable whether it's executable if [[ -n "$OPENSSL" ]] && [[ ! -x "$OPENSSL" ]]; then diff --git a/utils/update_client_sim_data.pl b/utils/update_client_sim_data.pl index 34f8b4d..61bf0d1 100755 --- a/utils/update_client_sim_data.pl +++ b/utils/update_client_sim_data.pl @@ -295,6 +295,12 @@ foreach my $client ( @$ssllabs ) { push @curves, "X25519"; } elsif ( $curve == 30 ) { push @curves, "X448"; } + elsif ( $curve == 31 ) { + push @curves, "brainpoolP256r1tls13"; } + elsif ( $curve == 32 ) { + push @curves, "brainpoolP384r1tls13"; } + elsif ( $curve == 33 ) { + push @curves, "brainpoolP512r1tls13"; } } $sim->{ellipticCurves} = "curves+=(\"" . (join ":", @curves) . "\")"; } From dc996ba2b993895fce09b2f08ce0cab3719ed617 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 28 Mar 2023 14:31:28 -0700 Subject: [PATCH 43/94] Find RSASSA-PSS certificates with TLS 1.3 This commit fixes get_server_certificate() so that it can obtain certificates with RSASSA-PSS subject public keys over TLS 1.3. --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 4e0115c..34d5586 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8015,9 +8015,9 @@ get_server_certificate() { [[ $(has_server_protocol "tls1_3") -eq 1 ]] && return 1 if "$HAS_TLS13" && "$HAS_SIGALGS" && [[ ! "$1" =~ tls1_3_EdDSA ]]; then if [[ "$1" =~ tls1_3_RSA ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -showcerts -connect $NODEIP:$PORT $PROXY $SNI -tls1_3 -tlsextdebug -status -msg -sigalgs PSS+SHA256:PSS+SHA384") $ERRFILE >$TMPFILE + $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -showcerts -connect $NODEIP:$PORT $PROXY $SNI -tls1_3 -tlsextdebug -status -msg -sigalgs PSS+SHA256:PSS+SHA384:PSS+SHA512:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512") $ERRFILE >$TMPFILE elif [[ "$1" =~ tls1_3_ECDSA ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -showcerts -connect $NODEIP:$PORT $PROXY $SNI -tls1_3 -tlsextdebug -status -msg -sigalgs ECDSA+SHA256:ECDSA+SHA384") $ERRFILE >$TMPFILE + $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -showcerts -connect $NODEIP:$PORT $PROXY $SNI -tls1_3 -tlsextdebug -status -msg -sigalgs ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512") $ERRFILE >$TMPFILE else return 1 fi @@ -8031,7 +8031,7 @@ get_server_certificate() { if [[ "$STARTTLS" =~ irc ]]; then return 1 elif [[ "$1" =~ tls1_3_RSA ]]; then - tls_sockets "04" "$TLS13_CIPHER" "all+" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,10,00,0e,08,04,08,05,08,06,04,01,05,01,06,01,02,01" + tls_sockets "04" "$TLS13_CIPHER" "all+" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,16,00,14,08,04,08,05,08,06,04,01,05,01,06,01,02,01,08,09,08,0a,08,0b" elif [[ "$1" =~ tls1_3_ECDSA ]]; then tls_sockets "04" "$TLS13_CIPHER" "all+" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,0a,00,08,04,03,05,03,06,03,02,03" elif [[ "$1" =~ tls1_3_EdDSA ]]; then From 04f7b34028d183d698bbf95f1c026a3bd72ec8e0 Mon Sep 17 00:00:00 2001 From: mum-viadee Date: Fri, 12 May 2023 13:53:54 +0200 Subject: [PATCH 44/94] Added SNI to openssl call for testing secure renegotiation --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 66c8a3c..1b8e45d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -16896,7 +16896,7 @@ run_renego() { local hint="" local jsonID="" local ssl_reneg_attempts=$SSL_RENEG_ATTEMPTS - # No SNI needed here as there won't be two different SSL stacks for one IP + # SNI is needed here as openssl return an error if missing "$HAS_TLS13" && [[ -z "$proto" ]] && proto="-no_tls1_3" @@ -16913,7 +16913,7 @@ run_renego() { fileout "$jsonID" "OK" "TLS 1.3 only server" "$cve" "$cwe" else # first fingerprint for the Line "Secure Renegotiation IS NOT" or "Secure Renegotiation IS " - $OPENSSL s_client $(s_client_options "$proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY") 2>&1 $TMPFILE 2>$ERRFILE + $OPENSSL s_client $(s_client_options "$proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") 2>&1 $TMPFILE 2>$ERRFILE if sclient_connect_successful $? $TMPFILE; then grep -iaq "Secure Renegotiation IS NOT" $TMPFILE sec_renego=$? # 0= Secure Renegotiation IS NOT supported From f0f6b1a4fbd4030041a2c63dfd55dfe4297a3096 Mon Sep 17 00:00:00 2001 From: mum-viadee Date: Fri, 12 May 2023 14:26:27 +0200 Subject: [PATCH 45/94] Typo in comment corrected --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 1b8e45d..cba67cb 100755 --- a/testssl.sh +++ b/testssl.sh @@ -16896,7 +16896,7 @@ run_renego() { local hint="" local jsonID="" local ssl_reneg_attempts=$SSL_RENEG_ATTEMPTS - # SNI is needed here as openssl return an error if missing + # SNI is needed here as openssl returns an error if missing "$HAS_TLS13" && [[ -z "$proto" ]] && proto="-no_tls1_3" From 93466806f530a97affba5691196e5880b757667a Mon Sep 17 00:00:00 2001 From: mum-viadee Date: Mon, 15 May 2023 08:13:21 +0200 Subject: [PATCH 46/94] Added SNI to openssl call for testing secure client-initiated renegotiation --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index cba67cb..13dfd8d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -16982,7 +16982,7 @@ run_renego() { else # We need up to two tries here, as some LiteSpeed servers don't answer on "R" and block. Thus first try in the background # msg enables us to look deeper into it while debugging - echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -connect $NODEIP:$PORT $PROXY") >$TMPFILE 2>>$ERRFILE & + echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & wait_kill $! $HEADER_MAXSLEEP if [[ $? -eq 3 ]]; then pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out" # it hung @@ -16990,7 +16990,7 @@ run_renego() { sec_client_renego=1 else # second try in the foreground as we are sure now it won't hang - echo R | $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY") >$TMPFILE 2>>$ERRFILE + echo R | $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE sec_client_renego=$? # 0 means client is renegotiating & doesn't return an error --> vuln! # 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output @@ -17011,7 +17011,7 @@ run_renego() { fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint" else (for ((i=0; i < ssl_reneg_attempts; i++ )); do echo R; sleep 1; done) | \ - $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY") >$TMPFILE 2>>$ERRFILE + $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE case $? in 0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)" fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint" From e33e0bc204a509757ea7ce5c319dd4df0a52b616 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 15 May 2023 15:04:59 +0200 Subject: [PATCH 47/94] Update testssl.sh clarify comment --- testssl.sh | 48082 +++++++++++++++++++++++++-------------------------- 1 file changed, 24041 insertions(+), 24041 deletions(-) diff --git a/testssl.sh b/testssl.sh index 13dfd8d..fd00779 100755 --- a/testssl.sh +++ b/testssl.sh @@ -1,24041 +1,24041 @@ -#!/usr/bin/env bash -# -# vim:ts=5:sw=5:expandtab -# we have a spaces softtab, that ensures readability with other editors too - -# testssl.sh is a program for spotting weak SSL/TLS encryption, ciphers, protocols and some -# vulnerabilities or features. It may or may be not distributed by your distribution. -# The upstream versions are available (please leave the links intact): -# -# Development version https://github.com/drwetter/testssl.sh -# Stable version https://testssl.sh -# File bugs at GitHub https://github.com/drwetter/testssl.sh/issues -# -# Project lead and initiator: Dirk Wetter, copyleft: 2007-today, contributions so far see CREDITS.md -# Main contributions from David Cooper -# Project lead and initiator: Dirk Wetter, copyleft: 2007-today. -# Main contributions from David Cooper. Further contributors see CREDITS.md . -# -# License: GPLv2, see https://opensource.org/licenses/gpl-2.0.php and -# accompanying license "LICENSE.txt". Redistribution + modification under this -# license permitted. -# If you enclose this program or parts of it in your software, it has to be -# accompanied by the same license (see link). Do not violate the license. -# If you do not agree to these terms, do not use it in the first place! -# -# OpenSSL, which is being used and maybe distributed via one of this projects' -# web sites, is subject to their licensing: https://www.openssl.org/source/license.txt -# -# The client simulation data comes from SSLlabs and is licensed to the 'Qualys SSL Labs -# Terms of Use' (v2.2), see https://www.ssllabs.com/downloads/Qualys_SSL_Labs_Terms_of_Use.pdf, -# stating a CC BY 3.0 US license: https://creativecommons.org/licenses/by/3.0/us/ -# -# Please note: USAGE WITHOUT ANY WARRANTY, THE SOFTWARE IS PROVIDED "AS IS". -# USE IT AT your OWN RISK! -# Seriously! The threat is you run this code on your computer and untrusted input e.g. -# could be supplied from a server you are querying. -# -# HISTORY: -# Back in 2006 it all started with a few openssl commands... -# That's because openssl is a such a good swiss army knife (see e.g. -# https://wiki.openssl.org/index.php/Command_Line_Utilities) that it was difficult to resist -# wrapping some shell commands around it, which I used for my pen tests. This is how -# everything started. -# Now it has grown up, it has bash socket support for most features, which has been basically -# replacing more and more functions of OpenSSL and some sockets functions serve as some kind -# of central functions. -# -# WHY BASH? -# Cross-platform is one of the three main goals of this script. Second: Ease of installation. -# No compiling, install gems, go to CPAN, use pip etc. Third: Easy to use and to interpret -# the results. -# /bin/bash including the builtin sockets fulfill all that. The socket checks in bash may sound -# cool and unique -- they are -- but probably you can achieve e.g. the same result with my favorite -# interactive shell: zsh (zmodload zsh/net/socket -- checkout zsh/net/tcp) too! Oh, and btw. -# ksh93 has socket support too. -# Also bash is quite powerful if you use it appropriately: It can operate on patterns, process lines -# and deal perfectly with regular expressions -- without external binaries. -# /bin/bash though is way more often used within Linux and it's perfect for cross platform support. -# MacOS X has it and also under Windows the MSYS2 extension or Cygwin as well as Bash on Windows (WSL) -# has /bin/bash. -# -# Q: So what's the difference to www.ssllabs.com/ssltest/ or sslcheck.globalsign.com/ ? -# A: As of now ssllabs only check 1) webservers 2) on standard ports, 3) reachable from the -# internet. And those examples above 4) are 3rd parties. If these restrictions are all fine -# with you and you need a management compatible rating -- go ahead and use those. -# -# But also if your fine with those restrictions: testssl.sh is meant as a tool in your hand -# and it's way more flexible. Oh, and did I mention testssl.sh is open source? -# -#################### Stop talking, action now #################### - - -########### Definition of error codes -# -declare -r ERR_BASH=255 # Bash version incorrect -declare -r ERR_CMDLINE=254 # Cmd line couldn't be parsed -declare -r ERR_FCREATE=253 # Output file couldn't be created -declare -r ERR_FNAMEPARSE=252 # Input file couldn't be parsed -declare -r ERR_NOSUPPORT=251 # Feature requested is not supported -declare -r ERR_OSSLBIN=250 # Problem with OpenSSL binary -declare -r ERR_DNSBIN=249 # Problem with DNS lookup binaries -declare -r ERR_OTHERCLIENT=248 # Other client problem -declare -r ERR_DNSLOOKUP=247 # Problem with resolving IP addresses or names -declare -r ERR_CONNECT=246 # Connectivity problem -declare -r ERR_CLUELESS=245 # Weird state, either though user options or testssl.sh -declare -r ERR_RESOURCE=244 # Resources testssl.sh needs couldn't be read -declare -r ERR_CHILD=242 # Child received a signal from master -declare -r ALLOK=0 # All is fine - - -[ -z "${BASH_VERSINFO[0]}" ] && printf "\n\033[1;35m Please make sure you're using \"bash\"! Bye...\033[m\n\n" >&2 && exit $ERR_BASH -[ $(kill -l | grep -c SIG) -eq 0 ] && printf "\n\033[1;35m Please make sure you're calling me without leading \"sh\"! Bye...\033[m\n\n" >&2 && exit $ERR_BASH -[ ${BASH_VERSINFO[0]} -lt 3 ] && printf "\n\033[1;35m Minimum requirement is bash 3.2. You have $BASH_VERSION \033[m\n\n" >&2 && exit $ERR_BASH -[ ${BASH_VERSINFO[0]} -le 3 ] && [ ${BASH_VERSINFO[1]} -le 1 ] && printf "\n\033[1;35m Minimum requirement is bash 3.2. You have $BASH_VERSION \033[m\n\n" >&2 && exit $ERR_BASH - -########### Debugging helpers + profiling -# -declare -r PS4='|${LINENO}> \011${FUNCNAME[0]:+${FUNCNAME[0]}(): }' -DEBUGTIME=${DEBUGTIME:-false} # https://stackoverflow.com/questions/5014823/how-to-profile-a-bash-shell-script-slow-startup#20855353 -DEBUG_ALLINONE=${DEBUG_ALLINONE:-false} # true: do debugging in one screen (old behavior for testssl.sh and bash3's default - # false: needed for performance analysis or useful for just having an extra file -DEBUG_ALLINONE=${SETX:-false} # SETX as a shortcut for old style debugging, overriding DEBUG_ALLINONE -if [[ "$SHELLOPTS" =~ xtrace ]]; then - if "$DEBUGTIME"; then - # separate debugging, doesn't mess up the screen, $DEBUGTIME determines whether we also do performance analysis - exec 42>&2 2> >(tee /tmp/testssl-$$.log | sed -u 's/^.*$/now/' | date -f - +%s.%N >/tmp/testssl-$$.time) - # BASH_XTRACEFD=42 - else - if ! "$DEBUG_ALLINONE"; then - exec 42>| /tmp/testssl-$$.log - BASH_XTRACEFD=42 - fi - fi -fi - -########### Traps! Make sure that temporary files are cleaned up after use in ANY case -# -trap "cleanup" EXIT -trap "sig_cleanup" INT QUIT TERM -trap "child_error" USR1 - - -########### Internal definitions -# -declare -r VERSION="3.2rc2" -declare -r SWCONTACT="dirk aet testssl dot sh" -[[ "$VERSION" =~ dev|rc|beta ]] && \ - SWURL="https://testssl.sh/dev/" || - SWURL="https://testssl.sh/" -if git rev-parse --is-inside-work-tree &>/dev/null; then - declare -r GIT_REL="$(git log --format='%h %ci' -1 2>/dev/null | awk '{ print $1" "$2" "$3 }')" - declare -r GIT_REL_SHORT="${GIT_REL%% *}" - declare -r REL_DATE_TIME="${GIT_REL#* }" - declare -r REL_DATE="${REL_DATE_TIME% *}" -fi -declare -r PROG_NAME="$(basename "$0")" -declare -r RUN_DIR="$(dirname "$0")" -declare -r SYSTEM="$(uname -s)" -declare -r SYSTEMREV="$(uname -r)" -HNAME="$(uname -n)" -HNAME="${HNAME%%.*}" -declare CMDLINE -CMDLINE_PARSED="" # This makes sure we don't let early fatal() write into files when files aren't created yet -declare -r -a CMDLINE_ARRAY=("$@") # When performing mass testing, the child processes need to be sent the -declare -a MASS_TESTING_CMDLINE # command line in the form of an array (see #702 and https://mywiki.wooledge.org/BashFAQ/050). -declare -a SKIP_TESTS=() # This array hold the checks to be skipped - - -########### Defining (and presetting) variables which can be changed -# -# Following variables make use of $ENV and can also be used like "= ./testssl.sh " -declare -x OPENSSL -OPENSSL_TIMEOUT=${OPENSSL_TIMEOUT:-""} # Default connect timeout with openssl before we call the server side unreachable -CONNECT_TIMEOUT=${CONNECT_TIMEOUT:-""} # Default connect timeout with sockets before we call the server side unreachable -PHONE_OUT=${PHONE_OUT:-false} # Whether testssl can retrieve CRLs and OCSP -FAST_SOCKET=${FAST_SOCKET:-false} # EXPERIMENTAL feature to accelerate sockets -- DO NOT USE it for production -COLOR=${COLOR:-2} # 3: Extra color (ciphers, curves), 2: Full color, 1: B/W only 0: No ESC at all -COLORBLIND=${COLORBLIND:-false} # if true, swap blue and green in the output -SHOW_EACH_C=${SHOW_EACH_C:-false} # where individual ciphers are tested show just the positively ones tested -SHOW_SIGALGO=${SHOW_SIGALGO:-false} # "secret" switch whether testssl.sh shows the signature algorithm for -E / -e -SNEAKY=${SNEAKY:-false} # is the referer and useragent we leave behind just usual? -QUIET=${QUIET:-false} # don't output the banner. By doing this you acknowledge usage term appearing in the banner -SSL_NATIVE=${SSL_NATIVE:-false} # we do per default bash sockets where possible "true": switch back to "openssl native" -ASSUME_HTTP=${ASSUME_HTTP:-false} # in seldom cases (WAF, old servers, grumpy SSL) service detection fails. "True" enforces HTTP checks -BASICAUTH=${BASICAUTH:-""} # HTTP basic auth credentials can be set here like user:pass -REQHEADER=${REQHEADER:-""} # HTTP custom request header can be set here like Header: content. Can be used multiple times. -BUGS=${BUGS:-""} # -bugs option from openssl, needed for some BIG IP F5 -WARNINGS=${WARNINGS:-""} # can be either off or batch -DEBUG=${DEBUG:-0} # 1: normal output the files in /tmp/ are kept for further debugging purposes - # 2: list more what's going on , also lists some errors of connections - # 3: slight hexdumps + other info, - # 4: display bytes sent via sockets - # 5: display bytes received via sockets - # 6: whole 9 yards -FAST=${FAST:-false} # preference: show only first cipher, run_allciphers with openssl instead of sockets -WIDE=${WIDE:-false} # whether to display for some options just ciphers or a table w hexcode/KX,Enc,strength etc. -MASS_TESTING_MODE=${MASS_TESTING_MODE:-serial} # can be serial or parallel. Subject to change -LOGFILE="${LOGFILE:-""}" # logfile if used -JSONFILE="${JSONFILE:-""}" # jsonfile if used -CSVFILE="${CSVFILE:-""}" # csvfile if used -HTMLFILE="${HTMLFILE:-""}" # HTML if used -FNAME=${FNAME:-""} # file name to read commands from -FNAME_PREFIX=${FNAME_PREFIX:-""} # output filename prefix, see --outprefix -APPEND=${APPEND:-false} # append to csv/json/html/log file -OVERWRITE=${OVERWRITE:-false} # overwriting csv/json/html/log file -[[ -z "$NODNS" ]] && declare NODNS # If unset it does all DNS lookups per default. "min" only for hosts or "none" at all -NXCONNECT=${NXCONNECT:-invalid.} # For WSL this helps avoiding DNS requests to "invalid." which windows seem to handle delayed -HAS_IPv6=${HAS_IPv6:-false} # if you have OpenSSL with IPv6 support AND IPv6 networking set it to yes -ALL_CLIENTS=${ALL_CLIENTS:-false} # do you want to run all client simulation form all clients supplied by SSLlabs? -OFFENSIVE=${OFFENSIVE:-true} # do you want to include offensive vulnerability tests which may cause blocking by an IDS? -ADDTL_CA_FILES="${ADDTL_CA_FILES:-""}" # single file with a CA in PEM format or comma separated lists of them - -########### Tuning vars which cannot be set by a cmd line switch. Use instead e.g "HEADER_MAXSLEEP=10 ./testssl.sh " -# -TESTSSL_INSTALL_DIR="${TESTSSL_INSTALL_DIR:-""}" # If you run testssl.sh and it doesn't find it necessary file automagically set TESTSSL_INSTALL_DIR -CA_BUNDLES_PATH="${CA_BUNDLES_PATH:-""}" # You can have your CA stores some place else -EXPERIMENTAL=${EXPERIMENTAL:-false} # a development hook which allows us to disable code -PROXY_WAIT=${PROXY_WAIT:-20} # waiting at max 20 seconds for socket reply through proxy -DNS_VIA_PROXY=${DNS_VIA_PROXY:-false} # do DNS lookups via proxy. --ip=proxy reverses this -IGN_OCSP_PROXY=${IGN_OCSP_PROXY:-false} # Also when --proxy is supplied it is ignored when testing for revocation via OCSP via --phone-out -HEADER_MAXSLEEP=${HEADER_MAXSLEEP:-5} # we wait this long before killing the process to retrieve a service banner / http header -MAX_SOCKET_FAIL=${MAX_SOCKET_FAIL:-2} # If this many failures for TCP socket connects are reached we terminate -MAX_OSSL_FAIL=${MAX_OSSL_FAIL:-2} # If this many failures for s_client connects are reached we terminate -MAX_STARTTLS_FAIL=${MAX_STARTTLS_FAIL:-2} # max number of STARTTLS handshake failures in plaintext phase -MAX_HEADER_FAIL=${MAX_HEADER_FAIL:-2} # If this many failures for HTTP GET are encountered we don't try again to get the header -MAX_WAITSOCK=${MAX_WAITSOCK:-10} # waiting at max 10 seconds for socket reply. There shouldn't be any reason to change this. -CCS_MAX_WAITSOCK=${CCS_MAX_WAITSOCK:-5} # for the two CCS payload (each). There shouldn't be any reason to change this. -HEARTBLEED_MAX_WAITSOCK=${HEARTBLEED_MAX_WAITSOCK:-8} # for the heartbleed payload. There shouldn't be any reason to change this. -STARTTLS_SLEEP=${STARTTLS_SLEEP:-10} # max time wait on a socket for STARTTLS. MySQL has a fixed value of 1 which can't be overwritten (#914) -FAST_STARTTLS=${FAST_STARTTLS:-true} # at the cost of reliability decrease the handshakes for STARTTLS -USLEEP_SND=${USLEEP_SND:-0.1} # sleep time for general socket send -USLEEP_REC=${USLEEP_REC:-0.2} # sleep time for general socket receive -HSTS_MIN=${HSTS_MIN:-180} # >=180 days is ok for HSTS - HSTS_MIN=$((HSTS_MIN * 86400)) # correct to seconds -HPKP_MIN=${HPKP_MIN:-30} # >=30 days should be ok for HPKP_MIN, practical hints? - HPKP_MIN=$((HPKP_MIN * 86400)) # correct to seconds -DAYS2WARN1=${DAYS2WARN1:-60} # days to warn before cert expires, threshold 1 -DAYS2WARN2=${DAYS2WARN2:-30} # days to warn before cert expires, threshold 2 -VULN_THRESHLD=${VULN_THRESHLD:-1} # if vulnerabilities to check >$VULN_THRESHLD we DON'T show a separate header line in the output each vuln. check -UNBRACKTD_IPV6=${UNBRACKTD_IPV6:-false} # some versions of OpenSSL (like Gentoo) don't support [bracketed] IPv6 addresses -NO_ENGINE=${NO_ENGINE:-false} # if there are problems finding the (external) openssl engine set this to true -declare -r CLIENT_MIN_FS=5 # number of ciphers needed to run a test for FS -CAPATH="${CAPATH:-/etc/ssl/certs/}" # Does nothing yet (FC has only a CA bundle per default, ==> openssl version -d) -SOCAT="${SOCAT:-}" # For now we would need this for STARTTLS injection - -MEASURE_TIME_FILE=${MEASURE_TIME_FILE:-""} -if [[ -n "$MEASURE_TIME_FILE" ]] && [[ -z "$MEASURE_TIME" ]]; then - MEASURE_TIME=true -else - MEASURE_TIME=${MEASURE_TIME:-false} -fi -DISPLAY_CIPHERNAMES="openssl" # display OpenSSL ciphername (but both OpenSSL and RFC ciphernames in wide mode) -declare UA_STD="TLS tester from $SWURL" -declare -r UA_SNEAKY="Mozilla/5.0 (X11; Linux x86_64; rv:94.0) Gecko/20100101 Firefox/94.0" -SSL_RENEG_ATTEMPTS=${SSL_RENEG_ATTEMPTS:-6} # number of times to check SSL Renegotiation - -########### Initialization part, further global vars just being declared here -# -LC_COLLATE="" # ensures certain regex patterns work as expected and aren't localized, see setup_lc_collate() -HAS_LOCALE=false -SYSTEM2="" # currently only being used for WSL = bash on windows -PRINTF="" # which external printf to use. Empty presets the internal one, see #1130 -CIPHERS_BY_STRENGTH_FILE="" -TLS_DATA_FILE="" # mandatory file for socket-based handshakes -OPENSSL="" # If you run this from GitHub it's ~/bin/openssl.$(uname).$(uname -m) otherwise /usr/bin/openssl -OPENSSL2="" # When running from GitHub, this will be openssl version >=1.1.1 (auto determined) -OPENSSL_LOCATION="" -IKNOW_FNAME=false -FIRST_FINDING=true # is this the first finding we are outputting to file? -JSONHEADER=true # include JSON headers and footers in HTML file, if one is being created -CSVHEADER=true # same for CSV -HTMLHEADER=true # same for HTML -SECTION_FOOTER_NEEDED=false # kludge for tracking whether we need to close the JSON section object -GIVE_HINTS=false # give an additional info to findings -SERVER_SIZE_LIMIT_BUG=false # Some servers have either a ClientHello total size limit or a 128 cipher limit (e.g. old ASAs) -MULTIPLE_CHECKS=false # need to know whether an MX record or a hostname resolves to multiple IPs to check -CHILD_MASS_TESTING=${CHILD_MASS_TESTING:-false} -PARENT_LOGFILE="" # logfile if mass testing and all output sent to a single file -PARENT_JSONFILE="" # jsonfile if mass testing and all output sent to a single file -PARENT_CSVFILE="" # csvfile if mass testing and all output sent to a single file -PARENT_HTMLFILE="" # HTML if mass testing and all output sent to a single file -TIMEOUT_CMD="" -HAD_SLEPT=0 -NR_SOCKET_FAIL=0 # Counter for socket failures -NR_OSSL_FAIL=0 # .. for OpenSSL connects -NR_STARTTLS_FAIL=0 # .. for STARTTLS failures -NR_HEADER_FAIL=0 # .. for HTTP_GET -PROTOS_OFFERED="" # This keeps which protocol is being offered. See has_server_protocol(). -TLS12_CIPHER_OFFERED="" # This contains the hexcode of a cipher known to be supported by the server with TLS 1.2 -CURVES_OFFERED="" # This keeps which curves have been detected. Just for error handling -NO_CIPHER_ORDER_LEVEL=5 # This is the finding level to report if the server does not enforce a cipher order for one or more protocol versions. -KNOWN_OSSL_PROB=false # We need OpenSSL a few times. This variable is an indicator if we can't connect. Eases handling -DETECTED_TLS_VERSION="" # .. as hex string, e.g. 0300 or 0303 -APP_TRAF_KEY_INFO="" # Information about the application traffic keys for a TLS 1.3 connection. -TLS13_ONLY=false # Does the server support TLS 1.3 ONLY? -OSSL_SHORTCUT=${OSSL_SHORTCUT:-false} # Hack: if during the scan turns out the OpenSSL binary supports TLS 1.3 would be a better choice, this enables it. -TLS_EXTENSIONS="" -TLS13_CERT_COMPRESS_METHODS="" -CERTIFICATE_TRANSPARENCY_SOURCE="" -V2_HELLO_CIPHERSPEC_LENGTH=0 -declare -r NPN_PROTOs="spdy/4a2,spdy/3,spdy/3.1,spdy/2,spdy/1,http/1.1" -# alpn_protos needs to be space-separated, not comma-separated, including odd ones observed @ facebook and others, old ones like h2-17 omitted as they could not be found -declare -r ALPN_PROTOs="h2 spdy/3.1 http/1.1 grpc-exp h2-fb spdy/1 spdy/2 spdy/3 stun.turn stun.nat-discovery webrtc c-webrtc ftp" -TEMPDIR="" -TMPFILE="" -ERRFILE="" -CLIENT_AUTH="none" -CLIENT_AUTH_CA_LIST="" -TLS_TICKETS=false -NO_SSL_SESSIONID=true -CERT_COMPRESSION=${CERT_COMPRESSION:-false} # secret flag to set in addition to --devel for certificate compression -HOSTCERT="" # File with host certificate, without intermediate certificate -HEADERFILE="" -HEADERVALUE="" -HTTP_STATUS_CODE="" -DH_GROUP_OFFERED="" -DH_GROUP_LEN_P=0 -KEY_SHARE_EXTN_NR="33" # The extension number for key_share was changed from 40 to 51 in TLSv1.3 draft 23. - # In order to support draft 23 and later in addition to earlier drafts, need to - # know which extension number to use. Note that it appears that a single - # ClientHello cannot advertise both draft 23 and later and earlier drafts. - # Preset may help to deal with STARTTLS + TLS 1.3 draft 23 and later but not earlier. -BAD_SERVER_HELLO_CIPHER=false # reserved for cases where a ServerHello doesn't contain a cipher offered in the ClientHello -GOST_STATUS_PROBLEM=false -PATTERN2SHOW="" -SOCK_REPLY_FILE="" -NW_STR="" -LEN_STR="" -SNI="" -POODLE="" # keep vulnerability status for TLS_FALLBACK_SCSV - -# Initialize OpenSSL variables (and others) -OSSL_NAME="" # openssl name, in case of LibreSSL it's LibreSSL -OSSL_VER="" # openssl version, will be auto-determined -OSSL_VER_MAJOR=0 -OSSL_VER_MINOR=0 -OSSL_VER_APPENDIX="none" -CLIENT_PROB_NO=1 - -GOOD_CA_BUNDLE="" # A bundle of CA certificates that can be used to validate the server's certificate -CERTIFICATE_LIST_ORDERING_PROBLEM=false # Set to true if server sends a certificate list that contains a certificate - # that does not certify the one immediately preceding it. (See RFC 8446, Section 4.4.2) -STAPLED_OCSP_RESPONSE="" -HAS_DNS_SANS=false # Whether the certificate includes a subjectAltName extension with a DNS name or an application-specific identifier type. -HAS_DH_BITS=${HAS_DH_BITS:-false} # These are variables which are set by find_openssl_binary() -HAS_CURVES=false -OSSL_SUPPORTED_CURVES="" -HAS_SSL2=false -HAS_SSL3=false -HAS_TLS13=false -HAS_X448=false -HAS_X25519=false -HAS_SIGALGS=false -HAS_PKUTIL=false -HAS_PKEY=false -HAS_NO_SSL2=false -HAS_NOSERVERNAME=false -HAS_CIPHERSUITES=false -HAS_SECLEVEL=false -HAS_COMP=false -HAS_NO_COMP=false -HAS_ALPN=false -HAS_NPN=false -HAS_FALLBACK_SCSV=false -HAS_PROXY=false -HAS_XMPP=false -HAS_XMPP_SERVER=false -HAS_POSTGRES=false -HAS_MYSQL=false -HAS_LMTP=false -HAS_SIEVE=false -HAS_NNTP=false -HAS_IRC=false -HAS_CHACHA20=false -HAS_AES128_GCM=false -HAS_AES256_GCM=false -HAS_ZLIB=false -HAS_UDS=false -HAS_UDS2=false -HAS_ENABLE_PHA=false -HAS_DIG=false -HAS_DIG_R=true -DIG_R="-r" -HAS_HOST=false -HAS_DRILL=false -HAS_NSLOOKUP=false -HAS_IDN=false -HAS_IDN2=false -HAS_AVAHIRESOLVE=false -HAS_DIG_NOIDNOUT=false -HAS_XXD=false - -OSSL_CIPHERS_S="" -PORT=443 # unless otherwise auto-determined, see below -NODE="" -NODEIP="" -rDNS="" -CORRECT_SPACES="" # Used for IPv6 and proper output formatting -IPADDRs="" -IP46ADDRs="" -LOCAL_A=false # Does the $NODEIP come from /etc/hosts? -LOCAL_AAAA=false # Does the IPv6 IP come from /etc/hosts? -XMPP_HOST="" -PROXYIP="" # $PROXYIP:$PROXPORT is your proxy if --proxy is defined ... -PROXYPORT="" # ... and openssl has proxy support -PROXY="" # Once check_proxy() executed it contains $PROXYIP:$PROXPORT -VULN_COUNT=0 -SERVICE="" # Is the server running an HTTP server, SMTP, POP or IMAP? -URI="" -CERT_FINGERPRINT_SHA2="" -RSA_CERT_FINGERPRINT_SHA2="" -STARTTLS_PROTOCOL="" -OPTIMAL_PROTO="" # Need this for IIS6 (sigh) + OpenSSL 1.0.2, otherwise some handshakes will fail see - # https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892 -STARTTLS_OPTIMAL_PROTO="" # Same for STARTTLS, see https://github.com/drwetter/testssl.sh/issues/188 -OPTIMAL_SOCKETS_PROTO="" # Same for tls_sockets(). -- not yet used -ALL_FAILED_SOCKETS=true # Set to true if all attempts to connect to server using tls_sockets/sslv2_sockets failed -TLS_TIME="" # To keep the value of TLS server timestamp -TLS_NOW="" # Similar -TLS_DIFFTIME_SET=false # Tells TLS functions to measure the TLS difftime or not -NOW_TIME="" -HTTP_TIME="" -HTTP_AGE="" # Age Header, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age + RFC 7234 -REQHEADERS=() -GET_REQ11="" -START_TIME=0 # time in epoch when the action started -END_TIME=0 # .. ended -SCAN_TIME=0 # diff of both: total scan time -LAST_TIME=0 # only used for performance measurements (MEASURE_TIME=true) -SERVER_COUNTER=0 # Counter for multiple servers - -TLS_LOW_BYTE="" # For "secret" development stuff, see -q below -HEX_CIPHER="" # -- " -- - -GRADE_CAP="" # Keeps track of the current grading cap -GRADE_CAP_REASONS=() # Keeps track of all the reasons why grades are capped -GRADE_WARNINGS=() # Keeps track of all the grade warnings -KEY_EXCH_SCORE=100 # Keeps track of the score for category 2 "Key Exchange Strength" -CIPH_STR_BEST=0 # Keeps track of the best bit size for category 3 "Cipher Strength" -CIPH_STR_WORST=100000 # Keeps track of the worst bit size for category 3 "Cipher Strength" - # Intentionally set very high, so it can be set to 0, if necessary -TRUSTED1ST="" # Contains the `-trusted_first` flag, if this version of openssl supports it - -########### Global variables for parallel mass testing -# -declare -r PARALLEL_SLEEP=1 # Time to sleep after starting each test -MAX_WAIT_TEST=${MAX_WAIT_TEST:-1200} # Maximum time (in seconds) to wait for a test to complete -MAX_PARALLEL=${MAX_PARALLEL:-20} # Maximum number of tests to run in parallel - # This value may be made larger on systems with faster processors -declare -a -i PARALLEL_TESTING_PID=() # process id for each child test (or 0 to indicate test has already completed) -declare -a PARALLEL_TESTING_CMDLINE=() # command line for each child test -declare -i NR_PARALLEL_TESTS=0 # number of parallel tests run -declare -i NEXT_PARALLEL_TEST_TO_FINISH=0 # number of parallel tests that have completed and have been processed -declare FIRST_JSON_OUTPUT=true # true if no output has been added to $JSONFILE yet. - - -########### Cipher suite information -# -declare -i TLS_NR_CIPHERS=0 -declare TLS_CIPHER_HEXCODE=() -declare TLS_CIPHER_OSSL_NAME=() -declare TLS_CIPHER_RFC_NAME=() -declare TLS_CIPHER_SSLVERS=() -declare TLS_CIPHER_KX=() -declare TLS_CIPHER_AUTH=() -declare TLS_CIPHER_ENC=() -declare TLS_CIPHER_EXPORT=() -declare TLS_CIPHER_OSSL_SUPPORTED=() -declare TLS13_OSSL_CIPHERS="TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256" - - -########### Some predefinitions: date, sed (we always use tests for binaries and NOT try to determine -# capabilities by querying the OS) -# -HAS_GNUDATE=false -HAS_FREEBSDDATE=false -HAS_OPENBSDDATE=false -if date -d @735275209 >/dev/null 2>&1; then - if date -r @735275209 >/dev/null 2>&1; then - # It can't do any conversion from a plain date output. - HAS_OPENBSDDATE=true - else - HAS_GNUDATE=true - fi -fi -# FreeBSD and OS X date(1) accept "-f inputformat", so do newer OpenBSD versions >~ 6.6. -date -j -f '%s' 1234567 >/dev/null 2>&1 && \ - HAS_FREEBSDDATE=true - -echo A | sed -E 's/A//' >/dev/null 2>&1 && \ - declare -r HAS_SED_E=true || \ - declare -r HAS_SED_E=false - -########### Terminal definitions -tty -s && \ - declare -r INTERACTIVE=true || \ - declare -r INTERACTIVE=false - -if [[ -z $TERM_WIDTH ]]; then # No batch file and no otherwise predefined TERM_WIDTH - if ! tput cols &>/dev/null || ! "$INTERACTIVE";then # Prevent tput errors if running non interactive - export TERM_WIDTH=${COLUMNS:-80} - else - export TERM_WIDTH=${COLUMNS:-$(tput cols)} # For custom line wrapping and dashes - fi -fi -TERM_CURRPOS=0 # Custom line wrapping needs alter the current horizontal cursor pos - - -########### Severity functions and globals -# -INFO=0 -OK=0 -LOW=1 -MEDIUM=2 -HIGH=3 -CRITICAL=4 -SEVERITY_LEVEL=0 - -set_severity_level() { - local severity=$1 - - if [[ "$severity" == LOW ]]; then - SEVERITY_LEVEL=$LOW - elif [[ "$severity" == MEDIUM ]]; then - SEVERITY_LEVEL=$MEDIUM - elif [[ "$severity" == HIGH ]]; then - SEVERITY_LEVEL=$HIGH - elif [[ "$severity" == CRITICAL ]]; then - SEVERITY_LEVEL=$CRITICAL - else - # WARN and FATAL will always be logged as the represent scanning problems - echo "Supported severity levels are LOW, MEDIUM, HIGH, CRITICAL!" - help 1 - fi -} - -show_finding() { - local severity=$1 - - [[ "$severity" == DEBUG || - ( "$severity" == INFO && $SEVERITY_LEVEL -le $INFO ) || - ( "$severity" == OK && $SEVERITY_LEVEL -le $OK ) || - ( "$severity" == LOW && $SEVERITY_LEVEL -le $LOW ) || - ( "$severity" == MEDIUM && $SEVERITY_LEVEL -le $MEDIUM ) || - ( "$severity" == HIGH && $SEVERITY_LEVEL -le $HIGH ) || - ( "$severity" == CRITICAL && $SEVERITY_LEVEL -le $CRITICAL ) || - "$severity" == WARN || - "$severity" == FATAL ]] -} - -########### Output functions - -# For HTML output, replace any HTML reserved characters with the entity name -html_reserved(){ - local output - "$do_html" || return 0 - output="${1//&/$'&'amp;}" - output="${output///$'&'gt;}" - output="${output//\"/$'&'quot;}" - output="${output//\'/$'&'apos;}" - printf -- "%s" "$output" - return 0 -} - -html_out() { - local outstr="$1" - - "$do_html" || return 0 - if [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]]; then - if [[ "$outstr" =~ [[:cntrl:]] ]]; then - outstr="$(sanitize_fileout "$outstr")" - fi - printf -- "%b" "$outstr" >> "$HTMLFILE" - fi -} - -# Removes non-printable chars in CSV, JSON, HTML, see #2330 -sanitize_fileout() { - tr -d '\000-\011\013-\037' <<< "$1" -} - -# Removes non-printable chars in terminal output (log files) -# We need to keep the color ANSI escape code x1b, o33, see #2330 -sanitize_termout() { - tr -d '\000-\011\013-\032\034-\037' <<< "$1" -} - -# This is intentionally the same. -safe_echo() { printf -- "%b" "$1"; } -tm_out() { printf -- "%b" "$1"; } -tmln_out() { printf -- "%b" "$1\n"; } - -out() { printf -- "%b" "$1"; html_out "$(html_reserved "$1")"; } -outln() { printf -- "%b" "$1\n"; html_out "$(html_reserved "$1")\n"; } - -#TODO: Still no shell injection safe but if just run it from the cmd line: that's fine - -# Color print functions, see also https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html -tm_liteblue() { [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && tm_out "\033[0;32m$1" || tm_out "\033[0;34m$1"; } || tm_out "$1"; tm_off; } # not yet used -pr_liteblue() { tm_liteblue "$1"; [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } || html_out "$(html_reserved "$1")"; } -tmln_liteblue() { tm_liteblue "$1"; tmln_out; } -prln_liteblue() { pr_liteblue "$1"; outln; } - -tm_blue() { [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && tm_out "\033[1;32m$1" || tm_out "\033[1;34m$1"; } || tm_out "$1"; tm_off; } # used for head lines of single tests -pr_blue() { tm_blue "$1"; [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } || html_out "$(html_reserved "$1")"; } -tmln_blue() { tm_blue "$1"; tmln_out; } -prln_blue() { pr_blue "$1"; outln; } - -# we should be able to use aliases here -tm_warning() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[0;35m$1" || tm_underline "$1"; tm_off; } # some local problem: one test cannot be done -tmln_warning() { tm_warning "$1"; tmln_out; } # litemagenta -pr_warning() { tm_warning "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || { [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }; } -prln_warning() { pr_warning "$1"; outln; } - -tm_magenta() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[1;35m$1" || tm_underline "$1"; tm_off; } # fatal error: quitting because of this! -tmln_magenta() { tm_magenta "$1"; tmln_out; } -# different as warning above? -pr_magenta() { tm_magenta "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || { [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }; } -prln_magenta() { pr_magenta "$1"; outln; } - -tm_litecyan() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[0;36m$1" || tm_out "$1"; tm_off; } # not yet used -tmln_litecyan() { tm_litecyan "$1"; tmln_out; } -pr_litecyan() { tm_litecyan "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -prln_litecyan() { pr_litecyan "$1"; outln; } - -tm_cyan() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[1;36m$1" || tm_out "$1"; tm_off; } # additional hint -tmln_cyan() { tm_cyan "$1"; tmln_out; } -pr_cyan() { tm_cyan "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -prln_cyan() { pr_cyan "$1"; outln; } - -tm_litegrey() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[0;37m$1" || tm_out "$1"; tm_off; } # ... https://github.com/drwetter/testssl.sh/pull/600#issuecomment-276129876 -tmln_litegrey() { tm_litegrey "$1"; tmln_out; } # not really usable on a black background, see .. -prln_litegrey() { pr_litegrey "$1"; outln; } -pr_litegrey() { tm_litegrey "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } - -tm_grey() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[1;30m$1" || tm_out "$1"; tm_off; } -pr_grey() { tm_grey "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -tmln_grey() { tm_grey "$1"; tmln_out; } -prln_grey() { pr_grey "$1"; outln; } - -tm_svrty_good() { [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && tm_out "\033[0;34m$1" || tm_out "\033[0;32m$1"; } || tm_out "$1"; tm_off; } # litegreen (liteblue), This is good -tmln_svrty_good() { tm_svrty_good "$1"; tmln_out; } -pr_svrty_good() { tm_svrty_good "$1"; [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } || html_out "$(html_reserved "$1")"; } -prln_svrty_good() { pr_svrty_good "$1"; outln; } - -tm_svrty_best() { [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && tm_out "\033[1;34m$1" || tm_out "\033[1;32m$1"; } || tm_out "$1"; tm_off; } # green (blue), This is the best -tmln_svrty_best() { tm_svrty_best "$1"; tmln_out; } -pr_svrty_best() { tm_svrty_best "$1"; [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } || html_out "$(html_reserved "$1")"; } -prln_svrty_best() { pr_svrty_best "$1"; outln; } - -tm_svrty_low() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[1;33m$1" || tm_out "$1"; tm_off; } # yellow brown | academic or minor problem -tmln_svrty_low() { tm_svrty_low "$1"; tmln_out; } -pr_svrty_low() { tm_svrty_low "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -prln_svrty_low() { pr_svrty_low "$1"; outln; } - -tm_svrty_medium() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[0;33m$1" || tm_out "$1"; tm_off; } # brown | it is not a bad problem but you shouldn't do this -pr_svrty_medium() { tm_svrty_medium "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -tmln_svrty_medium(){ tm_svrty_medium "$1"; tmln_out; } -prln_svrty_medium(){ pr_svrty_medium "$1"; outln; } - -tm_svrty_high() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[0;31m$1" || tm_bold "$1"; tm_off; } # litered -pr_svrty_high() { tm_svrty_high "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || { [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }; } -tmln_svrty_high() { tm_svrty_high "$1"; tmln_out; } -prln_svrty_high() { pr_svrty_high "$1"; outln; } - -tm_svrty_critical() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[1;31m$1" || tm_bold "$1"; tm_off; } # red -pr_svrty_critical() { tm_svrty_critical "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || { [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }; } -tmln_svrty_critical() { tm_svrty_critical "$1"; tmln_out; } -prln_svrty_critical() { pr_svrty_critical "$1"; outln; } - -tm_deemphasize() { tm_out "$1"; } # hook for a weakened screen output, see #600 -pr_deemphasize() { tm_deemphasize "$1"; html_out "$(html_reserved "$1")"; } -tmln_deemphasize() { tm_deemphasize "$1"; tmln_out; } -prln_deemphasize() { pr_deemphasize "$1"; outln; } - -# color=1 functions -tm_off() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[m"; } - -tm_bold() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[1m$1" || tm_out "$1"; tm_off; } -tmln_bold() { tm_bold "$1"; tmln_out; } -pr_bold() { tm_bold "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -prln_bold() { pr_bold "$1" ; outln; } - -NO_ITALICS=false -if [[ $TERM == screen ]]; then - NO_ITALICS=true -elif [[ $SYSTEM == OpenBSD ]]; then - NO_ITALICS=true -elif [[ $SYSTEM == FreeBSD ]]; then - if [[ ${SYSTEMREV%\.*} -le 9 ]]; then - NO_ITALICS=true - fi -fi -tm_italic() { { [[ "$COLOR" -ne 0 ]] && ! "$NO_ITALICS"; } && tm_out "\033[3m$1" || tm_out "$1"; tm_off; } -tmln_italic() { tm_italic "$1" ; tmln_out; } -pr_italic() { tm_italic "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -prln_italic() { pr_italic "$1"; outln; } - -tm_strikethru() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[9m$1" || tm_out "$1"; tm_off; } # ugly! -tmln_strikethru() { tm_strikethru "$1"; tmln_out; } -pr_strikethru() { tm_strikethru "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -prln_strikethru() { pr_strikethru "$1" ; outln; } - -tm_underline() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[4m$1" || tm_out "$1"; tm_off; } -tmln_underline() { tm_underline "$1"; tmln_out; } -pr_underline() { tm_underline "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -prln_underline() { pr_underline "$1"; outln; } - -tm_reverse() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[7m$1" || tm_out "$1"; tm_off; } -tm_reverse_bold() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[7m\033[1m$1" || tm_out "$1"; tm_off; } -pr_reverse() { tm_reverse "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -pr_reverse_bold() { tm_reverse_bold "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } - -#pr_headline() { pr_blue "$1"; } -#https://misc.flogisoft.com/bash/tip_colors_and_formatting - -#pr_headline() { [[ "$COLOR" -ge 2 ]] && out "\033[1;30m\033[47m$1" || out "$1"; tm_off; } -tm_headline() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[1m\033[4m$1" || tm_out "$1"; tm_off; } -tmln_headline() { tm_headline "$1"; tmln_out; } -pr_headline() { tm_headline "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } -pr_headlineln() { pr_headline "$1" ; outln; } - -tm_squoted() { tm_out "'$1'"; } -pr_squoted() { out "'$1'"; } -tm_dquoted() { tm_out "\"$1\""; } -pr_dquoted() { out "\"$1\""; } - -# either files couldn't be found or openssl isn't good enough (which shouldn't happen anymore) -tm_local_problem() { tm_warning "Local problem: $1"; } -tmln_local_problem() { tmln_warning "Local problem: $1"; } -pr_local_problem() { pr_warning "Local problem: $1"; } -prln_local_problem() { prln_warning "Local problem: $1"; } - -# general failure -tm_fixme() { tm_warning "Fixme: $1"; } -tmln_fixme() { tmln_warning "Fixme: $1"; } -pr_fixme() { pr_warning "Fixme: $1"; } -prln_fixme() { prln_warning "Fixme: $1"; } - -pr_url() { tm_out "$1"; html_out "$1"; } -pr_boldurl() { tm_bold "$1"; html_out "$1"; } - -### color switcher (see e.g. https://linuxtidbits.wordpress.com/2008/08/11/output-color-on-bash-scripts/ -### https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html -### no output support for HTML! -set_color_functions() { - local ncurses_tput=true - - if [[ $SYSTEM == OpenBSD ]] && [[ "$TERM" =~ xterm-256 ]]; then - export TERM=xterm - # OpenBSD can't handle 256 colors (yet) in xterm which might lead to ugly errors - # like "tput: not enough arguments (3) for capability `AF'". Not our fault but - # before we get blamed we fix it here. - fi - - # Empty all vars if we have COLOR=0 equals no escape code -- these are globals: - red="" - green="" - brown="" - blue="" - magenta="" - cyan="" - grey="" - yellow="" - off="" - bold="" - underline="" - italic="" - - type -p tput &>/dev/null || return 0 # Hey wait, do we actually have tput / ncurses ? - tput cols &>/dev/null || return 0 # tput under BSDs and GNUs doesn't work either (TERM undefined?) - tput sgr0 &>/dev/null || ncurses_tput=false - if [[ "$COLOR" -ge 2 ]]; then - if $ncurses_tput; then - red=$(tput setaf 1) - green=$(tput setaf 2) - brown=$(tput setaf 3) - blue=$(tput setaf 4) - magenta=$(tput setaf 5) - cyan=$(tput setaf 6) - grey=$(tput setaf 7) - yellow=$(tput setaf 3; tput bold) - else # this is a try for old BSD, see terminfo(5) - red=$(tput AF 1) - green=$(tput AF 2) - brown=$(tput AF 3) - blue=$(tput AF 4) - magenta=$(tput AF 5) - cyan=$(tput AF 6) - grey=$(tput AF 7) - yellow=$(tput AF 3; tput md) - fi - fi - if [[ "$COLOR" -ge 1 ]]; then - if $ncurses_tput; then - bold=$(tput bold) - underline=$(tput sgr 0 1 2>/dev/null) - italic=$(tput sitm) # This doesn't work on FreeBSDi (9,10) and OpenBSD ... - italic_end=$(tput ritm) # ... and this, too - off=$(tput sgr0) - else # this is a try for old BSD, see terminfo(5) - bold=$(tput md) - underline=$(tput us) - italic=$(tput ZH 2>/dev/null) # This doesn't work on FreeBSDi (9,10) and OpenBSD - italic_end=$(tput ZR 2>/dev/null) # ... probably entry missing in /etc/termcap - reverse=$(tput mr) - off=$(tput me) - fi - fi - # FreeBSD 10 understands ESC codes like 'echo -e "\e[3mfoobar\e[23m"', but also no tput for italics -} - -###### START universal helper function definitions ###### - -if [[ "${BASH_VERSINFO[0]}" == 3 ]]; then - # older bash can do this only (MacOS X), even SLES 11, see #697 - toupper() { tr 'a-z' 'A-Z' <<< "$1"; } - tolower() { tr 'A-Z' 'a-z' <<< "$1"; } -else - toupper() { echo -n "${1^^}"; } - tolower() { echo -n "${1,,}"; } -fi - -get_last_char() { - echo "${1:~0}" # "${string: -1}" would work too (both also in bash 3.2) -} - # Checking for last char. If already a separator supplied, we don't need an additional one -debugme() { - [[ "$DEBUG" -ge 2 ]] && "$@" >&2 - return 0 -} - -debugme1() { [[ "$DEBUG" -ge 1 ]] && "$@" >&2; } - -hex2dec() { - echo $((16#$1)) -} - -# convert decimal number < 256 to hex -dec02hex() { - printf "x%02x" "$1" -} - -# convert decimal number between 256 and < 256*256 to hex -dec04hex() { - local a=$(printf "%04x" "$1") - printf "x%02s, x%02s" "${a:0:2}" "${a:2:2}" -} - - -# trim spaces for BSD and old sed -count_lines() { - echo $(wc -l <<< "$1") -} - -count_words() { - echo $(wc -w <<< "$1") -} - -count_ciphers() { - echo $(wc -w <<< "${1//:/ }") -} - -count_chars() { - echo $(wc -c <<< "$1") -} - -newline_to_spaces() { - tr '\n' ' ' <<< "$1" | sed 's/ $//' -} - -colon_to_spaces() { - echo "${1//:/ }" -} - -strip_lf() { - tr -d '\n' <<< "$1" | tr -d '\r' -} - -strip_spaces() { - echo "${1// /}" -} - -# https://web.archive.org/web/20121022051228/http://codesnippets.joyent.com/posts/show/1816 -strip_leading_space() { - printf "%s" "${1#"${1%%[![:space:]]*}"}" -} -strip_trailing_space() { - printf "%s" "${1%"${1##*[![:space:]]}"}" -} - -is_number() { - [[ "$1" =~ ^[1-9][0-9]*$ ]] && \ - return 0 || \ - return 1 -} - -strip_quote() ( - # Note: parens in function definition here force this into a separate - # shell, preventing extglob from affecting the code outside this function - shopt -s extglob - # Remove color codes - OUT=${1//$'\e['*([0-9;])[a-zA-Z]} - # Replace quotes - OUT=${OUT//\"/\'} - strip_leading_space "$( - strip_trailing_space "$OUT" - )" -) - -# Converts a string containing PEM encoded data to one line. -pem_to_one_line() { - local pem="$1" - local header="" footer="" - - if [[ "$pem" =~ .*-+BEGIN\ [A-Za-z0-9]+-+ ]]; then - header="$BASH_REMATCH" - pem="${pem/$header/}" - fi - if [[ "$pem" =~ -+END\ [A-Za-z0-9]+-+.* ]]; then - footer="$BASH_REMATCH" - pem="${pem/$footer/}" - fi - pem="$(strip_spaces "$(newline_to_spaces "$pem")")" - [[ -n "$header" ]] && pem="$header\\\n$pem" - [[ -n "$footer" ]] && pem+="\\\n$footer" - printf -- "%s" "$pem" - return 0 -} - -is_ipv4addr() { - local octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" - local ipv4address="$octet\\.$octet\\.$octet\\.$octet" - - [[ -z "$1" ]] && return 1 - - # Check that $1 contains an IPv4 address and nothing else - [[ "$1" =~ $ipv4address ]] && [[ "$1" == $BASH_REMATCH ]] && \ - return 0 || \ - return 1 -} - -# See RFC 4291, Section 2.2 -is_ipv6addr() { - local ipv6seg="[0-9A-Fa-f]{1,4}" - local octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" - local ipv4address="$octet\\.$octet\\.$octet\\.$octet" - local ipv6address - - ipv6address="($ipv6seg:){7}(:|$ipv6seg)" - ipv6address+="|($ipv6seg:){6}(:|:$ipv6seg|$ipv4address)" - ipv6address+="|($ipv6seg:){5}(:|(:$ipv6seg){1,2}|:$ipv4address)" - ipv6address+="|($ipv6seg:){4}(:|(:$ipv6seg){1,3}|:($ipv6seg:){0,1}$ipv4address)" - ipv6address+="|($ipv6seg:){3}(:|(:$ipv6seg){1,4}|:($ipv6seg:){0,2}$ipv4address)" - ipv6address+="|($ipv6seg:){2}(:|(:$ipv6seg){1,5}|:($ipv6seg:){0,3}$ipv4address)" - ipv6address+="|($ipv6seg:){1}(:|(:$ipv6seg){1,6}|:($ipv6seg:){0,4}$ipv4address)" - ipv6address+="|:((:$ipv6seg){1,7}|:($ipv6seg:){0,5}$ipv4address)" - - [[ -z "$1" ]] && return 1 - - # Check that $1 contains an IPv4 address and nothing else - [[ "$1" =~ $ipv6address ]] && [[ "$1" == $BASH_REMATCH ]] && \ - return 0 || \ - return 1 -} - -join_by() { - # joins an array using a custom delimiter https://web.archive.org/web/20201222183540/https://stackoverflow.com/questions/1527049/how-can-i-join-elements-of-an-array-in-bash/17841619#17841619 - local d=$1 - shift - local f=$1 - shift - printf %s "$f" "${@/#/$d}"; -} - -###### END universal helper function definitions ###### - -###### START ServerHello/OpenSSL/F5 function definitions ###### - -#arg1: TLS 1.2 and below ciphers -#arg2: TLS 1.3 ciphers -#arg3: options (e.g., -V) -actually_supported_osslciphers() { - local ciphers="$1" - local tls13_ciphers="$TLS13_OSSL_CIPHERS" - local options="$3 " - - [[ "$2" != ALL ]] && tls13_ciphers="$2" - "$HAS_SECLEVEL" && [[ -n "$ciphers" ]] && ciphers="@SECLEVEL=0:$1" - # With OpenSSL 1.0.2 the only way to exclude SSLv2 ciphers is to use the -tls1 option. - # However, with newer versions of OpenSSL, the -tls1 option excludes TLSv1.2 ciphers. - if "$HAS_SSL2"; then - options="${options//-no_ssl2 /-tls1 }" - else - options="${options//-no_ssl2 /}" - fi - if "$HAS_CIPHERSUITES"; then - $OPENSSL ciphers $options $OSSL_CIPHERS_S -ciphersuites "$tls13_ciphers" "$ciphers" 2>/dev/null || echo "" - elif [[ -n "$tls13_ciphers" ]]; then - $OPENSSL ciphers $options $OSSL_CIPHERS_S "$tls13_ciphers:$ciphers" 2>/dev/null || echo "" - else - $OPENSSL ciphers $OSSL_CIPHERS_S $options "$ciphers" 2>/dev/null || echo "" - fi -} - -# Given a protocol (arg1) and a list of ciphers (arg2) that is formatted as -# ", xx,xx, xx,xx, xx,xx, xx,xx" remove any TLSv1.3 ciphers if the protocol -# is less than 04 and remove any TLSv1.2-only ciphers if the protocol is less -# than 03. -strip_inconsistent_ciphers() { - local -i proto=0x$1 - local cipherlist="$2" - - [[ $proto -lt 4 ]] && cipherlist="${cipherlist//, 13,0[0-9a-fA-F]/}" - if [[ $proto -lt 3 ]]; then - cipherlist="${cipherlist//, 00,3[b-fB-F]/}" - cipherlist="${cipherlist//, 00,40/}" - cipherlist="${cipherlist//, 00,6[7-9a-dA-D]/}" - cipherlist="${cipherlist//, 00,9[c-fC-F]/}" - cipherlist="${cipherlist//, 00,[abAB][0-9a-fA-F]/}" - cipherlist="${cipherlist//, 00,[cC][0-5]/}" - cipherlist="${cipherlist//, 16,[bB][7-9aA]/}" - cipherlist="${cipherlist//, [cC]0,2[3-9a-fA-F]/}" - cipherlist="${cipherlist//, [cC]0,3[01278a-fA-F]/}" - cipherlist="${cipherlist//, [cC]0,[4-9aA][0-9a-fA-F]/}" - cipherlist="${cipherlist//, [cC][cC],1[345]/}" - cipherlist="${cipherlist//, [cC][cC],[aA][89a-eA-E]/}" - fi - echo "$cipherlist" - return 0 -} - -# retrieve cipher from ServerHello (via openssl) -get_cipher() { - local cipher="" - local server_hello="$(cat -v "$1")" - # This and two other following instances are not best practice and normally a useless use of "cat", see - # https://web.archive.org/web/20160711205930/http://porkmail.org/era/unix/award.html#uucaletter - # However there seem to be cases where the preferred $(< "$1") logic has a problem. - # Especially with bash 3.2 (Mac OS X) and when on the server side binary chars - # are returned, see https://stackoverflow.com/questions/7427262/how-to-read-a-file-into-a-variable-in-shell#22607352 - # and https://github.com/drwetter/testssl.sh/issues/1292 - # Performance measurements showed no to barely measurable penalty (1s displayed in 9 tries). - - if [[ "$server_hello" =~ Cipher\ *:\ ([A-Z0-9]+-[A-Za-z0-9\-]+|TLS_[A-Za-z0-9_]+|SSL_[A-Za-z0-9_]+) ]]; then - cipher="${BASH_REMATCH##* }" - elif [[ "$server_hello" =~ (New|Reused)", "(SSLv[23]|TLSv1(\.[0-3])?(\/SSLv3)?)", Cipher is "([A-Z0-9]+-[A-Za-z0-9\-]+|TLS_[A-Za-z0-9_]+) ]]; then - cipher="${BASH_REMATCH##* }" - fi - tm_out "$cipher" -} - -# retrieve protocol from ServerHello (via openssl) -get_protocol() { - local protocol="" - local server_hello="$(cat -v "$1")" - - if [[ "$server_hello" =~ Protocol\ *:\ (SSLv[23]|TLSv1(\.[0-3])?) ]]; then - protocol="${BASH_REMATCH##* }" - elif [[ "$server_hello" =~ (New|Reused)", TLSv1.3, Cipher is "TLS_[A-Z0-9_]+ ]]; then - # Note: When OpenSSL prints "New, , Cipher is ", is the - # negotiated cipher, but is not the negotiated protocol. Instead, it is - # the SSL/TLS protocol that first defined . Since the ciphers that were - # first defined for TLSv1.3 may only be used with TLSv1.3, this line may be used - # to determine whether TLSv1.3 was negotiated, but if another protocol is specified - # on this line, then this line does not indicate the actual protocol negotiated. Also, - # only TLSv1.3 cipher suites have names that begin with TLS_, which provides additional - # assurance that the above match will only succeed if TLSv1.3 was negotiated. - protocol="TLSv1.3" - fi - tm_out "$protocol" -} - -# now some function for the integrated BIGIP F5 Cookie detector (see https://github.com/drwetter/F5-BIGIP-Decoder) - -f5_hex2ip() { - debugme echo "$1" - echo $((16#${1:0:2})).$((16#${1:2:2})).$((16#${1:4:2})).$((16#${1:6:2})) -} -f5_hex2ip6() { - debugme echo "$1" - echo "[${1:0:4}:${1:4:4}:${1:8:4}:${1:12:4}.${1:16:4}:${1:20:4}:${1:24:4}:${1:28:4}]" -} - -f5_determine_routeddomain() { - local tmp - tmp="${1%%o*}" - echo "${tmp/rd/}" -} - -f5_ip_oldstyle() { - local tmp - local a b c d - - tmp="${1/%.*}" # until first dot - tmp="$(printf "%08x" "$tmp")" # convert the whole thing to hex, now back to ip (reversed notation: - tmp="$(f5_hex2ip $tmp)" # transform to ip with reversed notation - IFS="." read -r a b c d <<< "$tmp" # reverse it - echo $d.$c.$b.$a -} - -f5_port_decode() { - local tmp - - tmp="$(strip_lf "$1")" # remove lf if there is one - tmp="${tmp/.0000/}" # to be sure remove trailing zeros with a dot - tmp="${tmp#*.}" # get the port - tmp="$(printf "%04x" "${tmp}")" # to hex - if [[ ${#tmp} -eq 4 ]]; then - : - elif [[ ${#tmp} -eq 3 ]]; then # fill it up with leading zeros if needed - tmp=0${tmp} - elif [[ ${#tmp} -eq 2 ]]; then - tmp=00${tmp} - fi - echo $((16#${tmp:2:2}${tmp:0:2})) # reverse order and convert it from hex to dec -} - -###### END universal helper function definitions ###### - - -###### START scoring function definitions ###### - -# Sets the grade cap to ARG1 -# arg1: A grade to set ("A", "B", "C", "D", "E", "F", "M", or "T") -# arg2: A reason why (e.g. "Vulnerable to CRIME") -set_grade_cap() { - "$do_rating" || return 0 - GRADE_CAP_REASONS+=("Grade capped to $1. $2") - - # Always set special attributes. These are hard caps, due to name mismatch or cert being invalid - if [[ "$1" == T || "$1" == M ]]; then - GRADE_CAP="$1" - # Only keep track of the lowest grade cap, since a higher grade cap won't do anything (F = lowest, A = highest) - elif [[ ! "$GRADE_CAP" > "$1" ]]; then - GRADE_CAP="$1" - fi - return 0 -} - -# Sets a grade warning, as specified by the grade specification -# arg1: A warning message -set_grade_warning() { - "$do_rating" || return 0 - GRADE_WARNINGS+=("$1") - return 0 -} - -# Sets the score for Category 2 (Key Exchange Strength) -# arg1: Short key algorithm ("EC", "DH", "RSA", ...), or "DHE" for ephemeral key size -# arg2: key size (number of bits) -set_key_str_score() { - local type=$1 - local size=$2 - - "$do_rating" || return 0 - - if [[ $type == EC || $type == EdDSA ]]; then - if [[ $size -lt 110 ]] && [[ $KEY_EXCH_SCORE -ge 20 ]]; then - KEY_EXCH_SCORE=20 - elif [[ $size -lt 123 ]] && [[ $KEY_EXCH_SCORE -ge 40 ]]; then - KEY_EXCH_SCORE=40 - elif [[ $size -lt 163 ]] && [[ $KEY_EXCH_SCORE -ge 80 ]]; then - KEY_EXCH_SCORE=80 - elif [[ $size -lt 225 ]] && [[ $KEY_EXCH_SCORE -ge 90 ]]; then - KEY_EXCH_SCORE=90 - fi - else - if [[ $size -lt 512 ]] && [[ $KEY_EXCH_SCORE -ge 20 ]]; then - KEY_EXCH_SCORE=20 - elif [[ $size -lt 1024 ]] && [[ $KEY_EXCH_SCORE -ge 40 ]]; then - KEY_EXCH_SCORE=40 - elif [[ $size -lt 2048 ]] && [[ $KEY_EXCH_SCORE -ge 80 ]]; then - KEY_EXCH_SCORE=80 - elif [[ $size -lt 4096 ]] && [[ $KEY_EXCH_SCORE -ge 90 ]]; then - KEY_EXCH_SCORE=90 - fi - fi - return 0 -} - -# Sets the best and worst bit size key, used to grade Category 3 (Cipher Strength) -# This function itself doesn't actually set a score; its just in the name to keep it logical (score == rating function) -# arg1: a bit size -set_ciph_str_score() { - local size=$1 - - "$do_rating" || return 0 - - [[ $size -gt $CIPH_STR_BEST ]] && CIPH_STR_BEST=$size - [[ $size -lt $CIPH_STR_WORST ]] && CIPH_STR_WORST=$size - - [[ $size -lt 112 || $size == None ]] && set_grade_cap "F" "Using cipher suites weaker than 112 bits" - - return 0 -} - -###### END scoring function definitions ###### - -##################### START output file formatting functions ######################### -#################### START JSON file functions #################### - -fileout_json_footer() { - if "$do_json"; then - if [[ "$SCAN_TIME" -eq 0 ]]; then - fileout_json_finding "scanTime" "WARN" "Scan interrupted" "" "" "" - elif [[ $SEVERITY_LEVEL -lt $LOW ]] ; then - # no scan time in --severity=low and above, also needed for Travis, hackish... - fileout_json_finding "scanTime" "INFO" $SCAN_TIME "" "" "" - fi - printf "]\n" >> "$JSONFILE" - fi - if "$do_pretty_json"; then - if [[ "$SCAN_TIME" -eq 0 ]]; then - echo -e " ],\n \"scanTime\" : \"Scan interrupted\"\n}" >> "$JSONFILE" - else - echo -e " ],\n \"scanTime\" : ${SCAN_TIME}\n}" >> "$JSONFILE" - fi - fi -} - -fileout_json_section() { - case $1 in - 0) echo -e " \"pretest\" : [" ;; - 1) echo -e " \"singleCipher\" : [" ;; - 2) echo -e ",\n \"protocols\" : [" ;; - 3) echo -e ",\n \"grease\" : [" ;; - 4) echo -e ",\n \"ciphers\" : [" ;; - 5) echo -e ",\n \"serverPreferences\" : [" ;; - 6) echo -e ",\n \"fs\" : [" ;; - 7) echo -e ",\n \"serverDefaults\" : [" ;; - 8) echo -e ",\n \"headerResponse\" : [" ;; - 9) echo -e ",\n \"vulnerabilities\" : [" ;; - 10) echo -e ",\n \"cipherTests\" : [" ;; - 11) echo -e ",\n \"browserSimulations\": [" ;; - 12) echo -e ",\n \"rating\" : [" ;; - *) echo "invalid section" ;; - esac -} - -fileout_section_header() { - local str="" - "$2" && str="$(fileout_section_footer false)" - "$do_pretty_json" && FIRST_FINDING=true && (printf "%s%s\n" "$str" "$(fileout_json_section "$1")") >> "$JSONFILE" - SECTION_FOOTER_NEEDED=true -} - -# arg1: whether to end object too -fileout_section_footer() { - "$do_pretty_json" && FIRST_FINDING=false && printf "\n ]" >> "$JSONFILE" - "$do_pretty_json" && "$1" && echo -e "\n }" >> "$JSONFILE" - SECTION_FOOTER_NEEDED=false -} - -fileout_json_print_parameter() { - local parameter="$1" - local filler="$2" - local value="$3" - local not_last="$4" - local spaces="" - - "$do_json" && \ - spaces=" " || \ - spaces=" " - if [[ -n "$value" ]] || [[ "$parameter" == finding ]]; then - if [[ "$value" =~ [[:cntrl:]] ]]; then - value="$(sanitize_fileout "$value")" - fi - printf -- "%b%b%b%b" "$spaces" "\"$parameter\"" "$filler" ": \"$value\"" >> "$JSONFILE" - "$not_last" && printf ",\n" >> "$JSONFILE" - fi -} - -fileout_json_finding() { - local target - local finding="$3" - local cve="$4" - local cwe="$5" - local hint="$6" - - if "$do_json"; then - "$FIRST_FINDING" || echo -n "," >> "$JSONFILE" - echo -e " {" >> "$JSONFILE" - fileout_json_print_parameter "id" " " "$1" true - fileout_json_print_parameter "ip" " " "$NODE/$NODEIP" true - fileout_json_print_parameter "port" " " "$PORT" true - fileout_json_print_parameter "severity" " " "$2" true - fileout_json_print_parameter "cve" " " "$cve" true - fileout_json_print_parameter "cwe" " " "$cwe" true - "$GIVE_HINTS" && fileout_json_print_parameter "hint" " " "$hint" true - fileout_json_print_parameter "finding" " " "$finding" false - echo -e "\n }" >> "$JSONFILE" - fi - if "$do_pretty_json"; then - if [[ "$1" == service ]]; then - if [[ $SERVER_COUNTER -gt 1 ]]; then - echo " ," >> "$JSONFILE" - elif ! "$FIRST_FINDING"; then - echo -n "," >> "$JSONFILE" - fi - target="$NODE" - $do_mx_all_ips && target="$URI" - echo -e " { - \"targetHost\" : \"$target\", - \"ip\" : \"$NODEIP\", - \"port\" : \"$PORT\", - \"rDNS\" : \"$rDNS\", - \"service\" : \"$finding\"," >> "$JSONFILE" - $do_mx_all_ips && echo -e " \"hostname\" : \"$NODE\"," >> "$JSONFILE" - else - ("$FIRST_FINDING" && echo -n " {" >> "$JSONFILE") || echo -n ",{" >> "$JSONFILE" - echo -e -n "\n" >> "$JSONFILE" - fileout_json_print_parameter "id" " " "$1" true - fileout_json_print_parameter "severity" " " "$2" true - fileout_json_print_parameter "cve" " " "$cve" true - fileout_json_print_parameter "cwe" " " "$cwe" true - "$GIVE_HINTS" && fileout_json_print_parameter "hint" " " "$hint" true - fileout_json_print_parameter "finding" " " "$finding" false - echo -e -n "\n }" >> "$JSONFILE" - fi - fi -} - -fileout_pretty_json_banner() { - local target - - if ! "$do_mass_testing"; then - [[ -z "$NODE" ]] && parse_hn_port "${URI}" - # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now --> wrong place - target="$NODE" - $do_mx_all_ips && target="$URI" - fi - - echo -e " \"Invocation\" : \"$PROG_NAME $CMDLINE\", - \"at\" : \"$HNAME:$OPENSSL_LOCATION\", - \"version\" : \"$VERSION $GIT_REL_SHORT\", - \"openssl\" : \"$OSSL_NAME $OSSL_VER from $OSSL_BUILD_DATE\", - \"startTime\" : \"$START_TIME\", - \"scanResult\" : [" -} - -fileout_banner() { - if "$JSONHEADER"; then - # "$do_json" && # here we maybe should add a banner, too - "$do_pretty_json" && FIRST_FINDING=true && (printf "%s\n" "$(fileout_pretty_json_banner)") >> "$JSONFILE" - fi -} - -fileout_separator() { - if "$JSONHEADER"; then - "$do_pretty_json" && echo " ," >> "$JSONFILE" - "$do_json" && echo -n "," >> "$JSONFILE" - fi -} - -fileout_footer() { - if "$JSONHEADER"; then - fileout_json_footer - fi - # CSV: no footer - return 0 -} - -fileout_insert_warning() { - # See #815. Make sure we don't mess up the JSON PRETTY format if we complain with a client side warning. - # This should only be called if an *extra* warning will be printed (previously: 'fileout "WARN" ' - # arg1: json identifier, arg2: normally "WARN", arg3: finding - # - # Also, we have to be careful with any form of mass testing so that a warning won't lead to an invalid JSON - # file. As any child will do any check as well (to be reconsidered later), we don't need also the parent to issue - # warnings upfront, see #1169. As a detection we'll use --file/-iL as in the children jobs it'll be removed: - [[ "$CMDLINE=" =~ --file ]] && return 0 - [[ "$CMDLINE=" =~ -iL ]] && return 0 - # Note we still have the message on screen + in HTML which is not as optimal as it could be - - if "$do_pretty_json" && "$JSONHEADER"; then - echo -e " \"clientProblem${CLIENT_PROB_NO}\" : [" >>"$JSONFILE" - CLIENT_PROB_NO=$((CLIENT_PROB_NO + 1)) - FIRST_FINDING=true # make sure we don't have a comma here - fi - fileout "$1" "$2" "$3" - if "$do_pretty_json"; then - if "$JSONHEADER"; then - echo -e "\n ]," >>"$JSONFILE" - else - echo -e ", " >>"$JSONFILE" - fi - FIRST_FINDING=true - fi -} - -# args: "id" "fqdn/ip" "port" "severity" "finding" "cve" "cwe" "hint" -# -fileout_csv_finding() { - local finding="$5" - - if [[ "$finding" =~ [[:cntrl:]] ]]; then - finding="$(sanitize_fileout "$finding")" - fi - safe_echo "\"$1\"," >> "$CSVFILE" - safe_echo "\"$2\"," >> "$CSVFILE" - safe_echo "\"$3\"," >> "$CSVFILE" - safe_echo "\"$4\"," >> "$CSVFILE" - safe_echo "\"$finding\"," >> "$CSVFILE" - safe_echo "\"$6\"," >> "$CSVFILE" - if "$GIVE_HINTS"; then - safe_echo "\"$7\"," >> "$CSVFILE" - safe_echo "\"$8\"\n" >> "$CSVFILE" - else - safe_echo "\"$7\"\n" >> "$CSVFILE" - fi -} - - -# ID, SEVERITY, FINDING, CVE, CWE, HINT -fileout() { - local severity="$2" - local cve="$4" - local cwe="$5" - local hint="$6" - - if { "$do_pretty_json" && [[ "$1" == service ]]; } || show_finding "$severity"; then - local finding=$(strip_lf "$(newline_to_spaces "$(strip_quote "$3")")") # additional quotes will mess up screen output - [[ -e "$JSONFILE" ]] && [[ ! -d "$JSONFILE" ]] && fileout_json_finding "$1" "$severity" "$finding" "$cve" "$cwe" "$hint" - "$do_csv" && [[ -n "$CSVFILE" ]] && [[ ! -d "$CSVFILE" ]] && \ - fileout_csv_finding "$1" "$NODE/$NODEIP" "$PORT" "$severity" "$finding" "$cve" "$cwe" "$hint" - "$FIRST_FINDING" && FIRST_FINDING=false - fi -} - - -json_header() { - local fname_prefix - local filename_provided=false - - if [[ -n "$PARENT_JSONFILE" ]]; then - [[ -n "$JSONFILE" ]] && fatal "Can't write to both $PARENT_JSONFILE and $JSONFILE" $ERR_CMDLINE - JSONFILE="$PARENT_JSONFILE" - fi - [[ -n "$JSONFILE" ]] && [[ ! -d "$JSONFILE" ]] && filename_provided=true - # Similar to HTML: Don't create headers and footers in the following scenarios: - # * no JSON/CSV output is being created. - # * mass testing is being performed and each test will have its own file. - # * this is an individual test within a mass test and all output is being placed in a single file. - ! "$do_json" && ! "$do_pretty_json" && JSONHEADER=false && return 0 - "$do_mass_testing" && ! "$filename_provided" && JSONHEADER=false && return 0 - "$CHILD_MASS_TESTING" && "$filename_provided" && [[ -n "$PARENT_JSONFILE" ]] && JSONHEADER=false && return 0 - - if "$do_display_only"; then - fname_prefix="local-ciphers" - elif "$do_mass_testing"; then - : - elif "$do_mx_all_ips"; then - fname_prefix="${FNAME_PREFIX}mx-${URI}" - else - # ensure NODE, URL_PATH, PORT, IPADDR and IP46ADDR are set - ! "$filename_provided" && [[ -z "$NODE" ]] && parse_hn_port "${URI}" - fname_prefix="${FNAME_PREFIX}${NODE}_p${PORT}" - fi - if [[ -z "$JSONFILE" ]]; then - JSONFILE="$fname_prefix-$(date +"%Y%m%d-%H%M".json)" - elif [[ -d "$JSONFILE" ]]; then - JSONFILE="$JSONFILE/${fname_prefix}-$(date +"%Y%m%d-%H%M".json)" - fi - # Silently reset APPEND var if the file doesn't exist as otherwise it won't be created - if "$APPEND" && [[ ! -s "$JSONFILE" ]]; then - APPEND=false - fi - if "$APPEND"; then - JSONHEADER=false - else - if [[ -s "$JSONFILE" ]]; then - "$OVERWRITE" || fatal "non-empty \"$JSONFILE\" exists. Either use \"--append\" or (re)move it" $ERR_FCREATE - cp /dev/null "$JSONFILE" - fi - "$do_json" && echo "[" > "$JSONFILE" - "$do_pretty_json" && echo "{" > "$JSONFILE" - fi - return 0 -} - - -csv_header() { - local fname_prefix - local filename_provided=false - - if [[ -n "$PARENT_CSVFILE" ]]; then - [[ -n "$CSVFILE" ]] && fatal "Can't write to both $PARENT_CSVFILE and $CSVFILE" $ERR_CMDLINE - CSVFILE="$PARENT_CSVFILE" - fi - [[ -n "$CSVFILE" ]] && [[ ! -d "$CSVFILE" ]] && filename_provided=true - # CSV similar to JSON - ! "$do_csv" && CSVHEADER=false && return 0 - "$do_mass_testing" && ! "$filename_provided" && CSVHEADER=false && return 0 - "$CHILD_MASS_TESTING" && "$filename_provided" && [[ -n "$PARENT_CSVFILE" ]] && CSVHEADER=false && return 0 - - if "$do_display_only"; then - fname_prefix="local-ciphers" - elif "$do_mass_testing"; then - : - elif "$do_mx_all_ips"; then - fname_prefix="${FNAME_PREFIX}mx-${URI}" - else - # ensure NODE, URL_PATH, PORT, IPADDR and IP46ADDR are set - ! "$filename_provided" && [[ -z "$NODE" ]] && parse_hn_port "${URI}" - fname_prefix="${FNAME_PREFIX}${NODE}_p${PORT}" - fi - if [[ -z "$CSVFILE" ]]; then - CSVFILE="${fname_prefix}-$(date +"%Y%m%d-%H%M".csv)" - elif [[ -d "$CSVFILE" ]]; then - CSVFILE="$CSVFILE/${fname_prefix}-$(date +"%Y%m%d-%H%M".csv)" - fi - # Silently reset APPEND var if the file doesn't exist as otherwise it won't be created - if "$APPEND" && [[ ! -s "$CSVFILE" ]]; then - APPEND=false - fi - if "$APPEND"; then - CSVHEADER=false - else - if [[ -s "$CSVFILE" ]]; then - "$OVERWRITE" || fatal "non-empty \"$CSVFILE\" exists. Either use \"--append\" or (re)move it" $ERR_FCREATE - cp /dev/null "$CSVFILE" - fi - touch "$CSVFILE" - if "$GIVE_HINTS"; then - fileout_csv_finding "id" "fqdn/ip" "port" "severity" "finding" "cve" "cwe" "hint" - else - fileout_csv_finding "id" "fqdn/ip" "port" "severity" "finding" "cve" "cwe" - fi - fi - return 0 -} - - -################# END JSON file functions. START HTML functions #################### - -html_header() { - local fname_prefix - local filename_provided=false - - if [[ -n "$PARENT_HTMLFILE" ]]; then - [[ -n "$HTMLFILE" ]] && fatal "Can't write to both $PARENT_HTMLFILE and $HTMLFILE" $ERR_CMDLINE - HTMLFILE="$PARENT_HTMLFILE" - fi - [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] && filename_provided=true - # Don't create HTML headers and footers in the following scenarios: - # * HTML output is not being created. - # * mass testing is being performed and each test will have its own HTML file. - # * this is an individual test within a mass test and all HTML output is being placed in a single file. - ! "$do_html" && HTMLHEADER=false && return 0 - "$do_mass_testing" && ! "$filename_provided" && HTMLHEADER=false && return 0 - "$CHILD_MASS_TESTING" && "$filename_provided" && [[ -n "$PARENT_HTMLFILE" ]] && HTMLHEADER=false && return 0 - - if "$do_display_only"; then - fname_prefix="local-ciphers" - elif "$do_mass_testing"; then - : - elif "$do_mx_all_ips"; then - fname_prefix="${FNAME_PREFIX}mx-${URI}" - else - # ensure NODE, URL_PATH, PORT, IPADDR and IP46ADDR are set - ! "$filename_provided" && [[ -z "$NODE" ]] && parse_hn_port "${URI}" - fname_prefix="${FNAME_PREFIX}${NODE}_p${PORT}" - fi - if [[ -z "$HTMLFILE" ]]; then - HTMLFILE="$fname_prefix-$(date +"%Y%m%d-%H%M".html)" - elif [[ -d "$HTMLFILE" ]]; then - HTMLFILE="$HTMLFILE/$fname_prefix-$(date +"%Y%m%d-%H%M".html)" - fi - # Silently reset APPEND var if the file doesn't exist as otherwise it won't be created - if "$APPEND" && [[ ! -s "$HTMLFILE" ]]; then - APPEND=false - fi - if "$APPEND"; then - HTMLHEADER=false - else - if [[ -s "$HTMLFILE" ]]; then - "$OVERWRITE" || fatal "non-empty \"$HTMLFILE\" exists. Either use \"--append\" or (re)move it" $ERR_FCREATE - cp /dev/null "$HTMLFILE" - fi - html_out "\n" - html_out "\n" - html_out "\n" - html_out "\n" - html_out "\n" - html_out "\n" - html_out "testssl.sh\n" - html_out "\n" - html_out "\n" - html_out "
    \n"
    -     fi
    -     return 0
    -}
    -
    -html_banner() {
    -     if "$CHILD_MASS_TESTING" && "$HTMLHEADER"; then
    -          html_out "## Scan started as: \"$PROG_NAME $CMDLINE\"\n"
    -          html_out "## at $HNAME:$OPENSSL_LOCATION\n"
    -          html_out "## version testssl: $VERSION ${GIT_REL_SHORT} from $REL_DATE\n"
    -          html_out "## version openssl: \"$OSSL_NAME $OSSL_VER\" from \"$OSSL_BUILD_DATE\")\n\n"
    -     fi
    -}
    -
    -html_footer() {
    -     if "$HTMLHEADER"; then
    -          html_out "
    \n" - html_out "\n" - html_out "\n" - fi - return 0 -} - -################# END HTML file functions #################### - -prepare_logging() { - # arg1: for testing mx records name we put a name of logfile in here, otherwise we get strange file names - local fname_prefix="$1" - local filename_provided=false - - if [[ -n "$PARENT_LOGFILE" ]]; then - [[ -n "$LOGFILE" ]] && fatal "Can't write to both $PARENT_LOGFILE and $LOGFILE" $ERR_CMDLINE - LOGFILE="$PARENT_LOGFILE" - fi - [[ -n "$LOGFILE" ]] && [[ ! -d "$LOGFILE" ]] && filename_provided=true - - # Similar to html_header(): - ! "$do_logging" && return 0 - "$do_mass_testing" && ! "$filename_provided" && return 0 - "$CHILD_MASS_TESTING" && "$filename_provided" && [[ -n "$PARENT_LOGFILE" ]] && return 0 - - [[ -z "$fname_prefix" ]] && fname_prefix="${FNAME_PREFIX}${NODE}_p${PORT}" - - if [[ -z "$LOGFILE" ]]; then - LOGFILE="$fname_prefix-$(date +"%Y%m%d-%H%M".log)" - elif [[ -d "$LOGFILE" ]]; then - # actually we were instructed to place all files in a DIR instead of the current working dir - LOGFILE="$LOGFILE/$fname_prefix-$(date +"%Y%m%d-%H%M".log)" - else - : # just for clarity: a log file was specified, no need to do anything else - fi - - if ! "$APPEND"; then - if [[ -s "$LOGFILE" ]]; then - "$OVERWRITE" || fatal "non-empty \"$LOGFILE\" exists. Either use \"--append\" or (re)move it" $ERR_FCREATE - cp /dev/null "$LOGFILE" - fi - fi - tmln_out "## Scan started as: \"$PROG_NAME $CMDLINE\"" >>"$LOGFILE" - tmln_out "## at $HNAME:$OPENSSL_LOCATION" >>"$LOGFILE" - tmln_out "## version testssl: $VERSION ${GIT_REL_SHORT} from $REL_DATE" >>"$LOGFILE" - tmln_out "## version openssl: \"$OSSL_VER\" from \"$OSSL_BUILD_DATE\")\n" >>"$LOGFILE" - exec > >(tee -a -i "$LOGFILE") -} - -################### END all file output functions ######################### - -# prints a string of n spaces (n < 80) -print_n_spaces() { - local -i n="$1" - local spaces=" " - - out "${spaces:0:n}" -} - -# prints out multiple lines in $1, left aligned by spaces in $2 -out_row_aligned() { - local first=true - - while read line; do - "$first" && \ - first=false || \ - out "$2" - outln "$line" - done <<< "$1" -} - -# prints text over multiple lines, trying to make no line longer than $max_width. -# Each line is indented with $spaces. -out_row_aligned_max_width() { - local text="$1" - local spaces="$2" - local -i max_width="$3" - local -i i len - local cr=$'\n' - local line - local first=true - - max_width=$max_width-${#spaces} - len=${#text} - while true; do - if [[ $len -lt $max_width ]]; then - # If the remaining text to print is shorter than $max_width, - # then just print it. - i=$len - else - # Find the final space character in the text that is less than - # $max_width characters into the remaining text, and make the - # text up to that space character the next line to print. - line="${text:0:max_width}" - line="${line% *}" - i="${#line}" - if [[ $i -eq $max_width ]]; then - # If there are no space characters in the first $max_width - # characters of the remaining text, then make the text up - # to the first space the next line to print. If there are - # no space characters in the remaining text, make the - # remaining text the next line to print. - line="${text#* }" - i=$len-${#line} - [[ $i -eq 0 ]] && i=$len - fi - fi - if ! "$first"; then - tm_out "${cr}${spaces}" - fi - tm_out "${text:0:i}" - [[ $i -eq $len ]] && break - len=$len-$i-1 - i+=1 - text="${text:i:len}" - first=false - [[ $len -eq 0 ]] && break - done - return 0 -} - -out_row_aligned_max_width_by_entry() { - local text="$1" - local spaces="$2" - local -i max_width="$3" - local print_function="$4" - local resp entry prev_entry=" " - - resp="$(out_row_aligned_max_width "$text" "$spaces" "$max_width")" - while read -d " " entry; do - if [[ -n "$entry" ]]; then - $print_function "$entry" - elif [[ -n "$prev_entry" ]]; then - outln; out " " - fi - out " " - prev_entry="$entry" - done <<< "$resp" -} - -print_fixed_width() { - local text="$1" - local -i len width="$2" - local print_function="$3" - - len=${#text} - $print_function "$text" - print_n_spaces "$((width-len+1))" -} - -# saves $TMPFILE or file supplied in $2 under name "$TEMPDIR/$NODEIP.$1". -# Note: after finishing $TEMPDIR will be removed unless DEBUG >=1 -tmpfile_handle() { - local savefile="$2" - [[ -z "$savefile" ]] && savefile=$TMPFILE -#FIXME: make sure/find out if we do not need $TEMPDIR/$NODEIP.$1" if debug=0. We would save fs access here - mv $savefile "$TEMPDIR/$NODEIP.$1" 2>/dev/null - [[ $ERRFILE =~ dev.null ]] && return 0 || \ - mv $ERRFILE "$TEMPDIR/$NODEIP.${1//.txt/}.errorlog" 2>/dev/null - return 0 -} - -# arg1: line with comment sign, tabs and so on -filter_input() { - sed -e 's/#.*$//' -e '/^$/d' <<< "$1" | tr -d '\n' | tr -d '\t' | tr -d '\r' -} - -# Dl's any URL (arg1) via HTTP 1.1 GET from port 80, arg2: file to store http body. -# Proxy is not honored yet (see cmd line switches) -- except when using curl or wget. -# There the environment variable is used automatically -# Currently it is being used by check_revocation_crl() only. -http_get() { - local proto z - local node="" query="" - local dl="$2" - local useragent="$UA_STD" - local jsonID="http_get" - - "$SNEAKY" && useragent="$UA_SNEAKY" - - if type -p curl &>/dev/null; then - if [[ -z "$PROXY" ]]; then - curl -s --noproxy '*' -A $''"$useragent"'' -o $dl "$1" - else - # for the sake of simplicity assume the proxy is using http - curl -s -x $PROXYIP:$PROXYPORT -A $''"$useragent"'' -o $dl "$1" - fi - return $? - elif type -p wget &>/dev/null; then - # wget has no proxy command line. We need to use http_proxy instead. And for the sake of simplicity - # assume the GET protocol we query is using http -- http_proxy is the $ENV not for the connection TO - # the proxy, but for the protocol we query THROUGH the proxy - if [[ -z "$PROXY" ]]; then - wget --no-proxy -q -U $''"$useragent"'' -O $dl "$1" - else - if [[ -z "$http_proxy" ]]; then - http_proxy=http://$PROXYIP:$PROXYPORT wget -q -U $''"$useragent"'' -O $dl "$1" - else - wget -q -U $''"$useragent"'' -O $dl "$1" - fi - fi - return $? - else - # Worst option: slower and hiccups with chunked transfers. Workaround for the - # latter is using HTTP/1.0. We do not support https here, yet. - # First the URL will be split - IFS=/ read -r proto z node query <<< "$1" - proto=${proto%:} - if [[ "$proto" != http ]]; then - pr_warning "protocol $proto not supported yet" - fileout "$jsonID" "DEBUG" "protocol $proto not supported yet" - return 6 - fi - if [[ -n $PROXY ]]; then - # PROXYNODE works better than PROXYIP on modern versions of squid. \ - # We don't reuse the code in fd_socket() as there's initial CONNECT which makes problems - if ! exec 33<> /dev/tcp/${PROXYNODE}/${PROXYPORT}; then - outln - pr_warning "$PROG_NAME: unable to open a socket to proxy $PROXYNODE:$PROXYPORT" - fileout "$jsonID" "DEBUG" "$PROG_NAME: unable to open a socket to proxy $PROXYNODE:$PROXYPORT" - return 6 - else - printf -- "%b" "GET $proto://$node/$query HTTP/1.0\r\nUser-Agent: $useragent\r\nHost: $node\r\nAccept: */*\r\n\r\n" >&33 - fi - else - IFS=/ read -r proto z node query <<< "$1" - exec 33<>/dev/tcp/$node/80 - printf -- "%b" "GET /$query HTTP/1.0\r\nUser-Agent: $useragent\r\nHost: $node\r\nAccept: */*\r\n\r\n" >&33 - fi - # Strip HTTP header. When in Debug Mode we leave the raw data in place - if [[ $DEBUG -ge 1 ]]; then - cat <&33 >${dl}.raw - cat ${dl}.raw | sed '1,/^[[:space:]]*$/d' >${dl} - else - cat <&33 | sed '1,/^[[:space:]]*$/d' >${dl} - fi - exec 33<&- - exec 33>&- - [[ -s "$dl" ]] && return 0 || return 1 - fi -} - -# Outputs the headers when downloading any URL (arg1) via HTTP 1.1 GET from port 80. -# Only works if curl or wget is available. -# There the environment variable is used automatically -# Currently it is being used by check_pwnedkeys() only. -http_get_header() { - local proto - local node="" query="" - local dl="$2" - local useragent="$UA_STD" - local jsonID="http_get_header" - local headers - local -i ret - - "$SNEAKY" && useragent="$UA_SNEAKY" - - if type -p curl &>/dev/null; then - if [[ -z "$PROXY" ]]; then - headers="$(curl --head -s --noproxy '*' -A $''"$useragent"'' "$1")" - else - # for the sake of simplicity assume the proxy is using http - headers="$(curl --head -s -x $PROXYIP:$PROXYPORT -A $''"$useragent"'' "$1")" - fi - ret=$? - [[ $ret -eq 0 ]] && tm_out "$headers" - return $ret - elif type -p wget &>/dev/null; then - # wget has no proxy command line. We need to use http_proxy instead. And for the sake of simplicity - # assume the GET protocol we query is using http -- http_proxy is the $ENV not for the connection TO - # the proxy, but for the protocol we query THROUGH the proxy - if [[ -z "$PROXY" ]]; then - headers="$(wget --no-proxy -q -S -U $''"$useragent"'' -O /dev/null "$1" 2>&1)" - else - if [[ -z "$http_proxy" ]]; then - headers="$(http_proxy=http://$PROXYIP:$PROXYPORT wget -q -S -U $''"$useragent"'' -O /dev/null "$1" 2>&1)" - else - headers="$(wget -q -S -U $''"$useragent"'' -O /dev/null "$1" 2>&1)" - fi - fi - ret=$? - [[ $ret -eq 0 ]] && tm_out "$headers" - # wget(1): "8: Server issued an error response.". Happens e.g. when 404 is returned. However also if the call wasn't correct (400) - # So we assume for now that everything is submitted correctly. We parse the error code too later - [[ $ret -eq 8 ]] && ret=0 && tm_out "$headers" - return $ret - else - return 1 - fi -} - -ldap_get() { - local ldif - local -i success - local crl="$1" - local tmpfile="$2" - local jsonID="$3" - - if type -p curl &>/dev/null; then - # proxy handling? - ldif="$(curl -s "$crl")" - [[ $? -eq 0 ]] || return 1 - awk '/certificateRevocationList/ { print $2 }' <<< "$ldif" | $OPENSSL base64 -d -A -out "$tmpfile" 2>/dev/null - [[ -s "$tmpfile" ]] || return 1 - return 0 - else - pr_litecyan " (for LDAP CRL check install \"curl\")" - fileout "$jsonID" "INFO" "LDAP CRL revocation check needs \"curl\"" - return 2 - fi -} - -# checks whether the public key in arg1 appears in the https://pwnedkeys.com/ database. -# arg1: file containing certificate -# arg2: public key algorithm -# arg3 key size -# Responses are as follows: -# 0 - not checked -# 1 - key not found in database -# 2 - key found in database -# 7 - network/proxy failure -check_pwnedkeys() { - local cert="$1" - local cert_key_algo="$2" - local -i cert_keysize="$3" - local pubkey curve response - - "$PHONE_OUT" || return 0 - - # https://pwnedkeys.com only keeps records on 1024 bit and larger RSA keys, - # as well as elliptic-curve keys on the P-256, P-384, and P-521 curves. - if [[ "$cert_key_algo" =~ RSA ]] || [[ "$cert_key_algo" =~ rsa ]]; then - [[ $cert_keysize -ge 1024 ]] || return 0 - elif [[ "$cert_key_algo" =~ ecdsa ]] || [[ "$cert_key_algo" == *ecPublicKey ]]; then - [[ $cert_keysize -eq 256 ]] || [[ $cert_keysize -eq 384 ]] || \ - [[ $cert_keysize -eq 521 ]] || return 0 - else - return 0 - fi - - pubkey="$($OPENSSL x509 -in "$cert" -pubkey -noout 2>/dev/null)" - # If it is an elliptic curve key, check that it is P-256, P-384, or P-521. - if [[ "$cert_key_algo" =~ ecdsa ]] || [[ "$cert_key_algo" == *ecPublicKey ]]; then - curve="$($OPENSSL ec -pubin -text <<< "$pubkey" 2>/dev/null)" - curve="${curve#*ASN1 OID: }" - [[ "$curve" == prime256v1* ]] || [[ "$curve" == secp384r1* ]] || \ - [[ "$curve" == secp521r1* ]] || return 0 - fi - fingerprint="$($OPENSSL pkey -pubin -outform DER <<< "$pubkey" 2>/dev/null | $OPENSSL dgst -sha256 -hex 2>/dev/null)" - fingerprint="${fingerprint#*= }" - response="$(http_get_header "https://v1.pwnedkeys.com/$fingerprint")" - # Handle curl's/wget's connectivity exit codes - case $? in - 4|5|7) return 7 ;; - 1|2|3|6) return 0 ;; - # unknown codes we just say "not checked" - esac - if [[ "$response" =~ "404 Not Found" ]]; then - return 1 - elif [[ "$response" =~ "200 OK" ]]; then - return 2 - else - return 0 - fi -} - -check_revocation_crl() { - local crl="$1" - local jsonID="$2" - local tmpfile="" - local scheme retcode - local -i success - - "$PHONE_OUT" || return 0 - [[ -n "$GOOD_CA_BUNDLE" ]] || return 0 - scheme="$(tolower "${crl%%://*}")" - # The code for obtaining CRLs only supports LDAP, HTTP, and HTTPS URLs. - [[ "$scheme" == http ]] || [[ "$scheme" == https ]] || [[ "$scheme" == ldap ]] || return 0 - tmpfile=$TEMPDIR/${NODE}-${NODEIP}.${crl##*\/} || exit $ERR_FCREATE - if [[ "$scheme" == ldap ]]; then - ldap_get "$crl" "$tmpfile" "$jsonID" - success=$? - else - http_get "$crl" "$tmpfile" - success=$? - fi - if [[ $success -eq 2 ]]; then - return 0 - elif [[ $success -ne 0 ]]; then - out ", " - pr_warning "retrieval of \"$crl\" failed" - fileout "$jsonID" "WARN" "CRL retrieval from $crl failed" - return 1 - fi - # -crl_download could be more elegant but is supported from 1.0.2 onwards only - $OPENSSL crl -inform DER -in "$tmpfile" -outform PEM -out "${tmpfile%%.crl}.pem" &>$ERRFILE - if [[ $? -ne 0 ]]; then - pr_warning "conversion of \"$tmpfile\" failed" - fileout "$jsonID" "WARN" "conversion of CRL to PEM format failed" - return 1 - fi - if grep -qe '-----BEGIN CERTIFICATE-----' $TEMPDIR/intermediatecerts.pem; then - $OPENSSL verify -crl_check -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE" "${tmpfile%%.crl}.pem") -untrusted $TEMPDIR/intermediatecerts.pem $HOSTCERT &> "${tmpfile%%.crl}.err" - else - $OPENSSL verify -crl_check -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE" "${tmpfile%%.crl}.pem") $HOSTCERT &> "${tmpfile%%.crl}.err" - fi - if [[ $? -eq 0 ]]; then - out ", " - pr_svrty_good "not revoked" - fileout "$jsonID" "OK" "not revoked" - else - retcode=$(awk '/error [1-9][0-9]? at [0-9]+ depth lookup:/ { if (!found) {print $2; found=1} }' "${tmpfile%%.crl}.err") - if [[ "$retcode" == 23 ]]; then # see verify_retcode_helper() - out ", " - pr_svrty_critical "revoked" - fileout "$jsonID" "CRITICAL" "revoked" - set_grade_cap "T" "Certificate revoked" - else - retcode="$(verify_retcode_helper "$retcode")" - out " $retcode" - retcode="${retcode#(}" - retcode="${retcode%)}" - fileout "$jsonID" "WARN" "$retcode" - set_grade_cap "T" "Issues with certificate $retcode" - if [[ $DEBUG -ge 2 ]]; then - outln - cat "${tmpfile%%.crl}.err" - fi - fi - fi - return 0 -} - -check_revocation_ocsp() { - local uri="$1" - local stapled_response="$2" - local jsonID="$3" - local tmpfile="" - local -i success - local response="" - local host_header="" - - "$PHONE_OUT" || [[ -n "$stapled_response" ]] || return 0 - [[ -n "$GOOD_CA_BUNDLE" ]] || return 0 - if [[ -n "$PROXY" ]] && ! "$IGN_OCSP_PROXY"; then - # see #1106 and https://github.com/openssl/openssl/issues/6965 - out ", " - pr_warning "revocation not tested as \"openssl ocsp\" doesn't support a proxy" - fileout "$jsonID" "WARN" "Revocation not tested as openssl ocsp doesn't support a proxy" - return 0 - fi - grep -qe '-----BEGIN CERTIFICATE-----' $TEMPDIR/intermediatecerts.pem || return 0 - tmpfile=$TEMPDIR/${NODE}-${NODEIP}.${uri##*\/} || exit $ERR_FCREATE - if [[ -n "$stapled_response" ]]; then - hex2binary "$stapled_response" > "$TEMPDIR/stapled_ocsp_response.dd" - $OPENSSL ocsp -no_nonce -respin "$TEMPDIR/stapled_ocsp_response.dd" \ - -issuer $TEMPDIR/hostcert_issuer.pem -verify_other $TEMPDIR/intermediatecerts.pem \ - -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE") -cert $HOSTCERT -text &> "$tmpfile" - else - host_header=${uri##http://} - host_header=${host_header%%/*} - if [[ "$OSSL_NAME" =~ LibreSSL ]]; then - host_header="-header Host ${host_header}" - elif [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.0* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* ]] || \ - [[ $OSSL_VER_MAJOR == 3 ]]; then - host_header="-header Host=${host_header}" - else - host_header="-header Host ${host_header}" - fi - $OPENSSL ocsp -no_nonce ${host_header} -url "$uri" \ - -issuer $TEMPDIR/hostcert_issuer.pem -verify_other $TEMPDIR/intermediatecerts.pem \ - -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE") -cert $HOSTCERT -text &> "$tmpfile" - fi - if [[ $? -eq 0 ]] && grep -Fq "Response verify OK" "$tmpfile"; then - response="$(grep -F "$HOSTCERT: " "$tmpfile")" - response="${response#$HOSTCERT: }" - response="${response%\.}" - if [[ "$response" =~ good ]]; then - out ", " - pr_svrty_good "not revoked" - fileout "$jsonID" "OK" "not revoked" - elif [[ "$response" =~ revoked ]]; then - out ", " - pr_svrty_critical "revoked" - fileout "$jsonID" "CRITICAL" "revoked" - set_grade_cap "T" "Certificate revoked" - else - out ", " - pr_warning "error querying OCSP responder" - fileout "$jsonID" "WARN" "$response" - if [[ $DEBUG -ge 2 ]]; then - outln - cat "$tmpfile" - else - out " ($response)" - fi - fi - else - [[ -s "$tmpfile" ]] || response="empty ocsp response" - [[ -z "$response" ]] && response="$(awk '/Responder Error:/ { print $3 }' "$tmpfile")" - [[ -z "$response" ]] && grep -Fq "Response Verify Failure" "$tmpfile" && response="unable to verify response" - [[ -z "$response" ]] && response="$(awk -F':' '/Code/ { print $NF }' $tmpfile)" - out ", " - pr_warning "error querying OCSP responder" - fileout "$jsonID" "WARN" "$response" - if [[ $DEBUG -ge 2 ]]; then - outln - [[ -s "$tmpfile" ]] && cat "$tmpfile" || echo "empty ocsp response" - elif [[ -n "$response" ]]; then - out " ($response)" - fi - fi -} - -wait_kill(){ - local pid=$1 # pid we wait for or kill - local maxsleep=$2 # how long we wait before killing - - HAD_SLEPT=0 - while true; do - if ! ps $pid >/dev/null ; then - return 0 # process terminated before didn't reach $maxsleep - fi - [[ "$DEBUG" -ge 6 ]] && ps $pid - sleep 1 - maxsleep=$((maxsleep - 1)) - HAD_SLEPT=$((HAD_SLEPT + 1)) - test $maxsleep -le 0 && break - done # needs to be killed: - kill $pid >&2 2>/dev/null - wait $pid 2>/dev/null # make sure pid terminated, see wait(1p) - return 3 # means killed -} - -# Convert date formats -- we always use GMT=UTC here -# argv1: source date string -# argv2: dest date string -if "$HAS_GNUDATE"; then # Linux and NetBSD - parse_date() { - LC_ALL=C TZ=GMT date -d "$1" "$2" - } -elif "$HAS_FREEBSDDATE"; then # FreeBSD, OS X and newer (~6.6) OpenBSD versions - parse_date() { - LC_ALL=C TZ=GMT date -j -f "$3" "$2" "$1" - } -elif "$HAS_OPENBSDDATE"; then - # We basically echo it as a conversion as we want it is too difficult. Approach for that would be: - # printf '%s\n' "$1" | awk '{ printf "%04d%02d%02d\n", $4, $2, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3}' - # 4: year, 1: month, 2: day, $3: time (e.g. "Dec 8 10:16:13 2016") - # This way we could also kind of convert args to epoch but as newer OpenBSDs "date" behave like FreeBSD - parse_date() { - local tmp="" - if [[ $2 == +%s* ]]; then - echo "${1// GMT}" - else - tmp="$(printf '%s\n' "$1" | awk '{ printf "%04d-%02d-%02d %08s\n", $4, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3, $2, $3 }')" - echo "${tmp%:*}" # remove seconds, result now is in line with GNU date 2016-12-08 10:16 - fi - } -else - parse_date() { - LC_ALL=C TZ=GMT date -j "$2" "$1" - } -fi - - -# Print $arg1 in binary format. arg1: An ASCII-HEX string -# The string represented by $arg1 may be binary data (a certificate or public -# key) or a text string (e.g., ASCII-encoded text). -hex2binary() { - local s="$1" - local -i i len remainder - - len=${#s} - [[ $len%2 -ne 0 ]] && return 1 - - if "$HAS_XXD"; then - xxd -r -p <<< "$s" - else - for (( i=0; i <= len-16 ; i+=16 )); do - printf -- "\x${s:i:2}\x${s:$((i+2)):2}\x${s:$((i+4)):2}\x${s:$((i+6)):2}\x${s:$((i+8)):2}\x${s:$((i+10)):2}\x${s:$((i+12)):2}\x${s:$((i+14)):2}" - done - - remainder=$((len-i)) - case $remainder in - 2) printf -- "\x${s:i:2}" ;; - 4) printf -- "\x${s:i:2}\x${s:$((i+2)):2}" ;; - 6) printf -- "\x${s:i:2}\x${s:$((i+2)):2}\x${s:$((i+4)):2}" ;; - 8) printf -- "\x${s:i:2}\x${s:$((i+2)):2}\x${s:$((i+4)):2}\x${s:$((i+6)):2}" ;; - 10) printf -- "\x${s:i:2}\x${s:$((i+2)):2}\x${s:$((i+4)):2}\x${s:$((i+6)):2}\x${s:$((i+8)):2}" ;; - 12) printf -- "\x${s:i:2}\x${s:$((i+2)):2}\x${s:$((i+4)):2}\x${s:$((i+6)):2}\x${s:$((i+8)):2}\x${s:$((i+10)):2}" ;; - 14) printf -- "\x${s:i:2}\x${s:$((i+2)):2}\x${s:$((i+4)):2}\x${s:$((i+6)):2}\x${s:$((i+8)):2}\x${s:$((i+10)):2}\x${s:$((i+12)):2}" ;; - esac - fi - return 0 -} - -# convert 414243 into ABC -hex2ascii() { - hex2binary $1 -} - -# arg1: text string -# Output a comma-separated ASCII-HEX string representation of the input string. -string_to_asciihex() { - local string="$1" - local -i i eos - local output="" - - eos=${#string}-1 - for (( i=0; i "$TMPFILE" - else - > "$TMPFILE" - fi - send_close_notify "$DETECTED_TLS_VERSION" - else - > "$TMPFILE" - fi - else - # SNI is not standardized for !HTTPS but fortunately for other protocols s_client doesn't seem to care - tm_out "$GET_REQ11" | $OPENSSL s_client $(s_client_options "$1 -quiet $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE & - wait_kill $! $HEADER_MAXSLEEP - was_killed=$? - fi - head $TMPFILE | grep -aq '^HTTP/' && SERVICE=HTTP - [[ -z "$SERVICE" ]] && head $TMPFILE | grep -waq "SMTP|ESMTP|Exim|IdeaSmtpServer|Kerio Connect|Postfix" && SERVICE=SMTP # I know some overlap here - [[ -z "$SERVICE" ]] && head $TMPFILE | grep -Ewaq "POP|Gpop|MailEnable POP3 Server|OK Dovecot|Cyrus POP3" && SERVICE=POP # I know some overlap here - [[ -z "$SERVICE" ]] && head $TMPFILE | grep -Ewaq "IMAP|IMAP4|Cyrus IMAP4IMAP4rev1|IMAP4REV1|Gimap" && SERVICE=IMAP # I know some overlap here - [[ -z "$SERVICE" ]] && head $TMPFILE | grep -aq FTP && SERVICE=FTP - [[ -z "$SERVICE" ]] && head $TMPFILE | grep -Eaqi "jabber|xmpp" && SERVICE=XMPP - [[ -z "$SERVICE" ]] && head $TMPFILE | grep -Eaqw "Jive News|InterNetNews|NNRP|INN|Kerio Connect|NNTP Service|Kerio MailServer|NNTP server" && SERVICE=NNTP - # MongoDB port 27017 will respond to a GET request with a mocked HTTP response - [[ "$SERVICE" == HTTP ]] && head $TMPFILE | grep -Eaqw "MongoDB" && SERVICE=MongoDB - debugme head -50 $TMPFILE | sed -e '//,$d' -e '//,$d' -e '/ skipping all HTTP checks" - echo "certificate-based authentication => skipping all HTTP checks" >$TMPFILE - fileout "${jsonID}" "INFO" "certificate-based authentication => skipping all HTTP checks" - else - out " Couldn't determine what's running on port $PORT" - if "$ASSUME_HTTP"; then - SERVICE=HTTP - out " -- ASSUME_HTTP set though" - fileout "${jsonID}" "DEBUG" "Couldn't determine service -- ASSUME_HTTP set" - else - out ", assuming no HTTP service => skipping all HTTP checks" - fileout "${jsonID}" "DEBUG" "Couldn't determine service, skipping all HTTP checks" - fi - fi - ;; - esac - - outln "\n" - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - -# 1: counter variable -# 2: threshold for this variable -# 3: string for first occurrence of problem -# 4: string for repeated occurrence of problem -# -connectivity_problem() { - if [[ $1 -lt $2 ]]; then - if "$TLS13_ONLY" && ! "$HAS_TLS13"; then - : - else - prln_warning " Oops: $3" - fi - return 0 - fi - if [[ $1 -ge $2 ]]; then - if [[ "$4" =~ openssl\ s_client\ connect ]] ; then - fatal "$4" $ERR_CONNECT "Consider increasing MAX_OSSL_FAIL (currently: $2)" - elif [[ "$4" =~ repeated\ TCP\ connect ]]; then - fatal "$4" $ERR_CONNECT "Consider increasing MAX_SOCKET_FAIL (currently: $2)" - fi - fatal "$4" $ERR_CONNECT - fi -} - - -#problems not handled: chunked -run_http_header() { - local header - local referer useragent - local url redirect - local jsonID="HTTP_status_code" - local spaces=" " - - HEADERFILE=$TEMPDIR/$NODEIP.http_header.txt - if [[ $NR_HEADER_FAIL -eq 0 ]]; then - # skip repeating this line if it's 2nd, 3rd,.. try - outln; pr_headlineln " Testing HTTP header response @ \"$URL_PATH\" " - outln - fi - if [[ $NR_HEADER_FAIL -ge $MAX_HEADER_FAIL ]]; then - # signal to caller we have a problem - return 1 - fi - - pr_bold " HTTP Status Code " - [[ -z "$1" ]] && url="/" || url="$1" - tm_out "$GET_REQ11" | $OPENSSL s_client $(s_client_options "$OPTIMAL_PROTO $BUGS -quiet -ign_eof -connect $NODEIP:$PORT $PROXY $SNI") >$HEADERFILE 2>$ERRFILE & - wait_kill $! $HEADER_MAXSLEEP - if [[ $? -eq 0 ]]; then - # Issue HTTP GET again as it properly finished within $HEADER_MAXSLEEP and didn't hang. - # Doing it again in the foreground to get an accurate header time - tm_out "$GET_REQ11" | $OPENSSL s_client $(s_client_options "$OPTIMAL_PROTO $BUGS -quiet -ign_eof -connect $NODEIP:$PORT $PROXY $SNI") >$HEADERFILE 2>$ERRFILE - NOW_TIME=$(date "+%s") - HTTP_TIME=$(awk -F': ' '/^date:/ { print $2 } /^Date:/ { print $2 }' $HEADERFILE) - HTTP_AGE=$(awk -F': ' '/^[aA][gG][eE]: / { print $2 }' $HEADERFILE) - HAD_SLEPT=0 - else - # 1st GET request hung and needed to be killed. Check whether it succeeded anyway: - if grep -Eiaq "XML|HTML|DOCTYPE|HTTP|Connection" $HEADERFILE; then - # correct by seconds we slept, HAD_SLEPT comes from wait_kill() - NOW_TIME=$(($(date "+%s") - HAD_SLEPT)) - HTTP_TIME=$(awk -F': ' '/^date:/ { print $2 } /^Date:/ { print $2 }' $HEADERFILE) - HTTP_AGE=$(awk -F': ' '/^[aA][gG][eE]: / { print $2 }' $HEADERFILE) - else - prln_warning " likely HTTP header requests failed (#lines: $(wc -l $HEADERFILE | awk '{ print $1 }'))" - [[ "$DEBUG" -lt 1 ]] && outln "Rerun with DEBUG>=1 and inspect $HEADERFILE\n" - fileout "HTTP_status_code" "WARN" "HTTP header request failed" - debugme cat $HEADERFILE - ((NR_HEADER_FAIL++)) - fi - fi - if [[ ! -s $HEADERFILE ]]; then - ((NR_HEADER_FAIL++)) - if [[ $NR_HEADER_FAIL -ge $MAX_HEADER_FAIL ]]; then - # Now, try to give a hint whether it would make sense to try with OpenSSL 1.1.0 or 1.1.1 instead - if [[ $CURVES_OFFERED == X448 ]] && ! "$HAS_X448" ; then - generic_nonfatal "HTTP header was repeatedly zero due to missing X448 curve." "${spaces}OpenSSL 1.1.1 might help. Skipping complete HTTP header section." - elif [[ $CURVES_OFFERED == X25519 ]] && ! "$HAS_X25519" ; then - generic_nonfatal "HTTP header was repeatedly zero due to missing X25519 curve." "${spaces}OpenSSL 1.1.0 might help. Skipping complete HTTP header section." - elif [[ $CURVES_OFFERED =~ X25519 ]] && [[ $CURVES_OFFERED =~ X448 ]] && ! "$HAS_X25519" && ! "$HAS_X448"; then - generic_nonfatal "HTTP header was repeatedly zero due to missing X25519/X448 curves." "${spaces}OpenSSL >=1.1.0 might help. Skipping complete HTTP header section." - else - # we could give more hints but these are the most likely cases - generic_nonfatal "HTTP header was repeatedly zero." "Skipping complete HTTP header section." - fi - KNOWN_OSSL_PROB=true - return 1 - else - pr_warning "HTTP header reply empty. " - fileout "$jsonID" "WARN" "HTTP header reply empty" - fi - fi - - # Populate vars for HTTP time - [[ -n "$HTTP_AGE" ]] && HTTP_AGE="$(strip_lf "$HTTP_AGE")" - [[ -n "$HTTP_TIME" ]] && HTTP_TIME="$(strip_lf "$HTTP_TIME")" - debugme echo "NOW_TIME: $NOW_TIME | HTTP_AGE: $HTTP_AGE | HTTP_TIME: $HTTP_TIME" - - # Quit on first empty line to catch 98% of the cases. Next pattern is there because the SEDs tested - # so far seem not to be fine with header containing x0d x0a (CRLF) which is the usual case. - # So we also trigger also on any sign on a single line which is not alphanumeric (plus _) - sed -e '/^$/q' -e '/^[^a-zA-Z_0-9]$/q' $HEADERFILE >$HEADERFILE.tmp - # Now to be more sure we delete from '<' or '{' maybe with a leading blank until the end - sed -e '/^ *<.*$/d' -e '/^ *{.*$/d' $HEADERFILE.tmp >$HEADERFILE - debugme echo -e "---\n $(< $HEADERFILE) \n---" - - HTTP_STATUS_CODE=$(awk '/^HTTP\// { print $2 }' $HEADERFILE 2>>$ERRFILE) - msg_thereafter=$(awk -F"$HTTP_STATUS_CODE" '/^HTTP\// { print $2 }' $HEADERFILE 2>>$ERRFILE) # dirty trick to use the status code as a - msg_thereafter=$(strip_lf "$msg_thereafter") # field separator, otherwise we need a loop with awk - debugme echo "Status/MSG: $HTTP_STATUS_CODE $msg_thereafter" - - [[ -n "$HTTP_STATUS_CODE" ]] && out " $HTTP_STATUS_CODE$msg_thereafter" - case $HTTP_STATUS_CODE in - 301|302|307|308) - redirect=$(grep -a '^Location' $HEADERFILE | sed 's/Location: //' | tr -d '\r\n') - out ", redirecting to \""; pr_url "$redirect"; out "\"" - if [[ $redirect =~ http:// ]]; then - pr_svrty_high " -- Redirect to insecure URL (NOT ok)" - fileout "insecure_redirect" "HIGH" "Redirect to insecure URL: \"$redirect\"" - fi - fileout "$jsonID" "INFO" "$HTTP_STATUS_CODE$msg_thereafter (\"$URL_PATH\")" - ;; - 200|204|403|405) - fileout "$jsonID" "INFO" "$HTTP_STATUS_CODE$msg_thereafter (\"$URL_PATH\")" - ;; - 206) - out " -- WHAT?" - fileout "$jsonID" "INFO" "$HTTP_STATUS_CODE$msg_thereafter (\"$URL_PATH\") -- WHAT?" - # partial content shouldn't happen - ;; - 400) - pr_cyan " (Hint: better try another URL)" - fileout "$jsonID" "INFO" "$HTTP_STATUS_CODE$msg_thereafter (\"$URL_PATH\") -- better try another URL" - ;; - 401) - grep -aq "^WWW-Authenticate" $HEADERFILE && out " "; out "$(strip_lf "$(grep -a "^WWW-Authenticate" $HEADERFILE)")" - fileout "$jsonID" "INFO" "$HTTP_STATUS_CODE$msg_thereafter (\"$URL_PATH\") -- $(grep -a "^WWW-Authenticate" $HEADERFILE)" - ;; - 404) - out " (Hint: supply a path which doesn't give a \"$HTTP_STATUS_CODE$msg_thereafter\")" - fileout "$jsonID" "INFO" "$HTTP_STATUS_CODE$msg_thereafter (\"$URL_PATH\")" - ;; - "") - prln_warning "No HTTP status code." - fileout "$jsonID" "WARN" "No HTTP status code" - return 1 - ;; - *) - pr_warning ". Oh, didn't expect \"$HTTP_STATUS_CODE$msg_thereafter\"" - fileout "$jsonID" "WARN" "Unexpected $HTTP_STATUS_CODE$msg_thereafter @ \"$URL_PATH\"" - ;; - esac - outln - - # we don't call "tmpfile_handle ${FUNCNAME[0]}.txt" as we need the header file in other functions! - return 0 -} - -# Borrowed from Glenn Jackman, see https://unix.stackexchange.com/users/4667/glenn-jackman -# -match_ipv4_httpheader() { - local octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" - local ipv4address="$octet\\.$octet\\.$octet\\.$octet" - local excluded_header="pagespeed|page-speed|^Content-Security-Policy|^MicrosoftSharePointTeamServices|^X-OWA-Version|^Location|^Server: " - local your_ip_msg="(check if it's your IP address or e.g. a cluster IP)" - local headers result - local first=true - local spaces=" " - local jsonID="ipv4_in_header" - local cwe="CWE-212" - local cve="" - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - - # Exclude some headers as they are mistakenly identified as ipv4 address. Issues #158, #323. - # Also facebook used to have a CSP rule for 127.0.0.1 - headers="$(grep -Evai "$excluded_header" $HEADERFILE)" - if [[ "$headers" =~ $ipv4address ]]; then - pr_bold " IPv4 address in header " - while read line; do - [[ "$line" =~ $ipv4address ]] || continue - result=$(strip_lf "$line") - if ! $first; then - out "$spaces" - your_ip_msg="" - else - first=false - fi - pr_svrty_medium "$result" - outln "\n$spaces$your_ip_msg" - fileout "$jsonID" "MEDIUM" "$result $your_ip_msg" "$cve" "$cwe" - done <<< "$headers" - fi -} - - -run_http_date() { - local difftime - local spaces=" " - jsonID="HTTP_clock_skew" - - if [[ $SERVICE != HTTP ]] || [[ "$CLIENT_AUTH" == required ]]; then - return 0 - fi - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - pr_bold " HTTP clock skew " - if [[ -n "$HTTP_TIME" ]]; then - if "$HAS_OPENBSDDATE"; then - # We won't normalize the date under an OpenBSD thus no subtraction is feasible - outln "remote: $HTTP_TIME" - out "${spaces}local: $(LC_ALL=C TZ=GMT date "+%a, %d %b %Y %T %Z")" - fileout "$jsonID" "INFO" "$HTTP_TIME - $(TZ=GMT date "+%a, %d %b %Y %T %Z")" - else - # modifying the global from string to a number - HTTP_TIME="$(parse_date "$HTTP_TIME" "+%s" "%a, %d %b %Y %T %Z" 2>>$ERRFILE)" - difftime=$((HTTP_TIME + HTTP_AGE - NOW_TIME)) - [[ $difftime != "-"* ]] && [[ $difftime != "0" ]] && difftime="+$difftime" - # process was killed, so we need to add an error - [[ $HAD_SLEPT -ne 0 ]] && difftime="$difftime (± 1.5)" - out "$difftime sec from localtime"; - fileout "$jsonID" "INFO" "$difftime seconds from localtime" - fi - if [[ -n "$HTTP_TIME" ]]; then - # out " (HTTP header time: $HTTP_TIME)" - fileout "HTTP_headerTime" "INFO" "$HTTP_TIME" - fi - if [[ -n "$HTTP_AGE" ]]; then - outln - pr_bold " HTTP Age" - out " (RFC 7234) $HTTP_AGE" - fileout "HTTP_headerAge" "INFO" "$HTTP_AGE seconds" - fi - else - out "Got no HTTP time, maybe try different URL?"; - fileout "$jsonID" "INFO" "Got no HTTP time, maybe try different URL?" - fi - debugme tm_out ", HTTP_TIME + HTTP_AGE in epoch: $HTTP_TIME / $HTTP_AGE" - outln - match_ipv4_httpheader "$1" - return 0 -} - - -# HEADERFILE needs to contain the HTTP header (made sure by invoker) -# arg1: key=word to match -# arg2: hint for fileout() if double header -# arg3: indentation, i.e string w spaces -# arg4: whether we need a CR before "misconfiguration" -# returns: -# 0 if header not found -# 1-n nr of headers found, then in HEADERVALUE the first value from key -# -match_httpheader_key() { - local key="$1" - local spaces="$3" - local first=$4 - local -i nr=0 - - nr=$(grep -Eaic "^ *$key:" $HEADERFILE) - if [[ $nr -eq 0 ]]; then - HEADERVALUE="" - return 0 - elif [[ $nr -eq 1 ]]; then - HEADERVALUE="$(grep -Eia "^ *$key:" $HEADERFILE)" - HEADERVALUE="${HEADERVALUE#*:}" # remove leading part=key to colon - HEADERVALUE="$(strip_lf "$HEADERVALUE")" - HEADERVALUE="$(strip_leading_space "$HEADERVALUE")" - "$first" || out "$spaces" - return 1 - else - "$first" || out "$spaces" - pr_svrty_medium "misconfiguration: " - pr_italic "$key" - pr_svrty_medium " ${nr}x" - outln " -- checking first one only" - out "$spaces" - HEADERVALUE="$(grep -Fai "$key:" $HEADERFILE | head -1)" - HEADERVALUE="${HEADERVALUE#*:}" - HEADERVALUE="$(strip_lf "$HEADERVALUE")" - HEADERVALUE="$(strip_leading_space "$HEADERVALUE")" - [[ $DEBUG -ge 2 ]] && tm_italic "$HEADERVALUE" && tm_out "\n$spaces" - fileout "${2}_multiple" "MEDIUM" "Multiple $2 headers. Using first header: $HEADERVALUE" - return $nr - fi -} - -includeSubDomains() { - if grep -aiqw includeSubDomains "$1"; then - pr_svrty_good ", includeSubDomains" - return 0 - else - pr_litecyan ", just this domain" - return 1 - fi -} - -preload() { - if grep -aiqw preload "$1"; then - pr_svrty_good ", preload" - return 0 - else - return 1 - fi -} - - -run_hsts() { - local hsts_age_sec - local hsts_age_days - local spaces=" " - local jsonID="HSTS" - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - pr_bold " Strict Transport Security " - match_httpheader_key "Strict-Transport-Security" "HSTS" "$spaces" "true" - if [[ $? -ne 0 ]]; then - echo "$HEADERVALUE" >$TMPFILE - hsts_age_sec="${HEADERVALUE//[^0-9]/}" - debugme echo "hsts_age_sec: $hsts_age_sec" - if [[ -n $hsts_age_sec ]]; then - hsts_age_days=$(( hsts_age_sec / 86400)) - else - hsts_age_days=-1 - fi - if [[ $hsts_age_days -eq -1 ]]; then - pr_svrty_medium "misconfiguration: HSTS max-age (recommended > $HSTS_MIN seconds = $((HSTS_MIN/86400)) days ) is required but missing" - fileout "${jsonID}_time" "MEDIUM" "misconfiguration, parameter max-age (recommended > $HSTS_MIN seconds = $((HSTS_MIN/86400)) days) missing" - set_grade_cap "A" "HSTS max-age is misconfigured" - elif [[ $hsts_age_sec -eq 0 ]]; then - pr_svrty_low "HSTS max-age is set to 0. HSTS is disabled" - fileout "${jsonID}_time" "LOW" "0. HSTS is disabled" - set_grade_cap "A" "HSTS is disabled" - elif [[ $hsts_age_sec -ge $HSTS_MIN ]]; then - pr_svrty_good "$hsts_age_days days" ; out "=$hsts_age_sec s" - fileout "${jsonID}_time" "OK" "$hsts_age_days days (=$hsts_age_sec seconds) > $HSTS_MIN seconds" - else - pr_svrty_medium "$hsts_age_sec s = $hsts_age_days days is too short ( >= $HSTS_MIN seconds recommended)" - fileout "${jsonID}_time" "MEDIUM" "max-age too short. $hsts_age_days days (=$hsts_age_sec seconds) < $HSTS_MIN seconds" - set_grade_cap "A" "HSTS max-age is too short" - fi - if includeSubDomains "$TMPFILE"; then - fileout "${jsonID}_subdomains" "OK" "includes subdomains" - else - fileout "${jsonID}_subdomains" "INFO" "only for this domain" - fi - if preload "$TMPFILE"; then - fileout "${jsonID}_preload" "OK" "domain IS marked for preloading" - else - fileout "${jsonID}_preload" "INFO" "domain is NOT marked for preloading" - #FIXME: To be checked against preloading lists, - # e.g. https://dxr.mozilla.org/mozilla-central/source/security/manager/boot/src/nsSTSPreloadList.inc - # https://chromium.googlesource.com/chromium/src/+/master/net/http/transport_security_state_static.json - fi - else - pr_svrty_low "not offered" - fileout "$jsonID" "LOW" "not offered" - set_grade_cap "A" "HSTS is not offered" - fi - outln - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - - -run_hpkp() { - local -i hpkp_age_sec - local -i hpkp_age_days - local -i hpkp_nr_keys - local hpkp_spki hpkp_spki_hostcert - local -a backup_spki - local spaces=" " - local spaces_indented=" " - local certificate_found=false - local -i i nrsaved - local first_hpkp_header - local spki - local ca_hashes="$TESTSSL_INSTALL_DIR/etc/ca_hashes.txt" - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - pr_bold " Public Key Pinning " - grep -aiw '^Public-Key-Pins' $HEADERFILE >$TMPFILE # TMPFILE includes report-only - if [[ $? -eq 0 ]]; then - if [[ $(grep -aci '^Public-Key-Pins:' $TMPFILE) -gt 1 ]]; then - pr_svrty_medium "Misconfiguration, multiple Public-Key-Pins headers" - outln ", taking first line" - fileout "HPKP_error" "MEDIUM" "multiple Public-Key-Pins in header" - first_hpkp_header="$(grep -ai '^Public-Key-Pins:' $TMPFILE | head -1)" - # we only evaluate the keys here, unless they a not present - out "$spaces " - set_grade_cap "A" "Problems with HTTP Public Key Pinning (HPKP)" - elif [[ $(grep -aci '^Public-Key-Pins-Report-Only:' $TMPFILE) -gt 1 ]]; then - outln "Multiple HPKP headers (Report-Only), taking first line" - fileout "HPKP_notice" "INFO" "multiple Public-Key-Pins-Report-Only in header" - first_hpkp_header="$(grep -ai '^Public-Key-Pins-Report-Only:' $TMPFILE | head -1)" - out "$spaces " - elif [[ $(grep -Eaci '^Public-Key-Pins:|^Public-Key-Pins-Report-Only:' $TMPFILE) -eq 2 ]]; then - outln "Public-Key-Pins + Public-Key-Pins-Report-Only detected. Continue with first one" - first_hpkp_header="$(grep -ai '^Public-Key-Pins:' $TMPFILE)" - out "$spaces " - elif [[ $(grep -aci '^Public-Key-Pins:' $TMPFILE) -eq 1 ]]; then - first_hpkp_header="$(grep -ai '^Public-Key-Pins:' $TMPFILE)" - else - outln "Public-Key-Pins-Only detected" - first_hpkp_header="$(grep -ai '^Public-Key-Pins-Report-Only:' $TMPFILE)" - out "$spaces " - fileout "HPKP_SPKIs" "INFO" "Only Public-Key-Pins-Report-Only" - fi - - # remove leading Public-Key-Pins* and convert it to multiline arg - sed -e 's/Public-Key-Pins://g' -e s'/Public-Key-Pins-Report-Only://' <<< "$first_hpkp_header" | \ - tr ';' '\n' | sed -e 's/\"//g' -e 's/^ //' >$TMPFILE - - hpkp_nr_keys=$(grep -ac pin-sha $TMPFILE) - if [[ $hpkp_nr_keys -eq 1 ]]; then - pr_svrty_high "Only one key pinned (NOT ok), means the site may become unavailable in the future, " - fileout "HPKP_SPKIs" "HIGH" "Only one key pinned" - set_grade_cap "A" "Problems with HTTP Public Key Pinning (HPKP)" - else - pr_svrty_good "$hpkp_nr_keys" - out " keys, " - fileout "HPKP_SPKIs" "OK" "$hpkp_nr_keys keys pinned in header" - fi - - # print key=value pair with awk, then strip non-numbers, to be improved with proper parsing of key-value with awk - if "$HAS_SED_E"; then - hpkp_age_sec=$(awk -F= '/max-age/{max_age=$2; print max_age}' $TMPFILE | sed -E 's/[^[:digit:]]//g') - else - hpkp_age_sec=$(awk -F= '/max-age/{max_age=$2; print max_age}' $TMPFILE | sed -r 's/[^[:digit:]]//g') - fi - hpkp_age_days=$((hpkp_age_sec / 86400)) - if [[ $hpkp_age_sec -ge $HPKP_MIN ]]; then - pr_svrty_good "$hpkp_age_days days" ; out "=$hpkp_age_sec s" - fileout "HPKP_age" "OK" "HPKP age is set to $hpkp_age_days days ($hpkp_age_sec sec)" - else - out "$hpkp_age_sec s = " - pr_svrty_medium "$hpkp_age_days days (< $HPKP_MIN s = $((HPKP_MIN / 86400)) days is not good enough)" - fileout "HPKP_age" "MEDIUM" "age is set to $hpkp_age_days days ($hpkp_age_sec sec) < $HPKP_MIN s = $((HPKP_MIN / 86400)) days is not good enough." - set_grade_cap "A" "Problems with HTTP Public Key Pinning (HPKP)" - fi - - if includeSubDomains "$TMPFILE"; then - fileout "HPKP_subdomains" "INFO" "is valid for subdomains as well" - else - fileout "HPKP_subdomains" "INFO" "is valid for this domain only" - fi - if preload "$TMPFILE"; then - fileout "HPKP_preload" "INFO" "IS marked for browser preloading" - else - fileout "HPKP_preload" "INFO" "NOT marked for browser preloading" - fi - - # Get the SPKIs first - spki=$(tr ';' '\n' < $TMPFILE | tr -d ' ' | tr -d '\"' | awk -F'=' '/pin.*=/ { print $2 }') - debugme tmln_out "\n$spki" - - # Look at the host certificate first - if [[ ! -s "$HOSTCERT" ]]; then - get_host_cert || return 1 - # no host certificate - fi - - hpkp_spki_hostcert="$($OPENSSL x509 -in $HOSTCERT -pubkey -noout 2>/dev/null | grep -v PUBLIC | \ - $OPENSSL base64 -d 2>/dev/null | $OPENSSL dgst -sha256 -binary 2>/dev/null | $OPENSSL base64 2>/dev/null)" - hpkp_ca="$($OPENSSL x509 -in $HOSTCERT -issuer -noout 2>/dev/null |sed 's/^.*CN=//' | sed 's/\/.*$//')" - - # Get keys/hashes from intermediate certificates - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS $PROXY -showcerts -connect $NODEIP:$PORT $SNI") $TMPFILE 2>$ERRFILE - # Place the server's certificate in $HOSTCERT and any intermediate - # certificates that were provided in $TEMPDIR/intermediatecerts.pem - # https://backreference.org/2010/05/09/ocsp-verification-with-openssl/ - awk -v n=-1 "/Certificate chain/ {start=1} - /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } - inc { print > (\"$TEMPDIR/level\" n \".crt\") } - /---END CERTIFICATE-----/{ inc=0 }" $TMPFILE - nrsaved=$(count_words "$(echo $TEMPDIR/level?.crt 2>/dev/null)") - rm $TEMPDIR/level0.crt 2>/dev/null - - printf ""> "$TEMPDIR/intermediate.hashes" - if [[ $nrsaved -ge 2 ]]; then - for cert_fname in $TEMPDIR/level?.crt; do - hpkp_spki_ca="$($OPENSSL x509 -in "$cert_fname" -pubkey -noout 2>/dev/null | grep -v PUBLIC | $OPENSSL base64 -d 2>/dev/null | - $OPENSSL dgst -sha256 -binary 2>/dev/null | $OPENSSL enc -base64 2>/dev/null)" - hpkp_name="$(get_cn_from_cert $cert_fname)" - hpkp_ca="$($OPENSSL x509 -in $cert_fname -issuer -noout 2>/dev/null |sed 's/^.*CN=//' | sed 's/\/.*$//')" - [[ -n $hpkp_name ]] || hpkp_name=$($OPENSSL x509 -in "$cert_fname" -subject -noout 2>/dev/null | sed 's/^subject= //') - echo "$hpkp_spki_ca $hpkp_name" >> "$TEMPDIR/intermediate.hashes" - done - fi - - # This is where the matching magic starts. First host, intermediate, then root certificate from the supplied stores - spki_match=false - has_backup_spki=false - i=0 - for hpkp_spki in $spki; do - certificate_found=false - # compare collected SPKIs against the host certificate - if [[ "$hpkp_spki_hostcert" == "$hpkp_spki" ]] || [[ "$hpkp_spki_hostcert" == "$hpkp_spki=" ]]; then - certificate_found=true # We have a match - spki_match=true - out "\n$spaces_indented Host cert: " - pr_svrty_good "$hpkp_spki" - fileout "HPKP_$hpkp_spki" "OK" "SPKI $hpkp_spki matches the host certificate" - fi - debugme tm_out "\n $hpkp_spki | $hpkp_spki_hostcert" - - # Check for intermediate match - if ! "$certificate_found"; then - hpkp_matches=$(grep "$hpkp_spki" $TEMPDIR/intermediate.hashes 2>/dev/null) - if [[ -n $hpkp_matches ]]; then # hpkp_matches + hpkp_spki + '=' - # We have a match - certificate_found=true - spki_match=true - out "\n$spaces_indented Sub CA: " - pr_svrty_good "$hpkp_spki" - ca_cn="$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< $"$hpkp_matches" )" - pr_italic " $ca_cn" - fileout "HPKP_$hpkp_spki" "OK" "SPKI $hpkp_spki matches Intermediate CA \"$ca_cn\" pinned in the HPKP header" - fi - fi - - # we compare now against a precompiled list of SPKIs against the ROOT CAs we have in $ca_hashes - if ! "$certificate_found"; then - hpkp_matches=$(grep -h "$hpkp_spki" $ca_hashes 2>/dev/null | sort -u) - if [[ -n $hpkp_matches ]]; then - certificate_found=true # root CA found - spki_match=true - if [[ $(count_lines "$hpkp_matches") -eq 1 ]]; then - # replace by awk - match_ca=$(sed "s/[a-zA-Z0-9\+\/]*=* *//" <<< "$hpkp_matches") - else - match_ca="" - - fi - ca_cn="$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< $"$hpkp_matches" )" - if [[ "$match_ca" == "$hpkp_ca" ]]; then # part of the chain - out "\n$spaces_indented Root CA: " - pr_svrty_good "$hpkp_spki" - pr_italic " $ca_cn" - fileout "HPKP_$hpkp_spki" "INFO" "SPKI $hpkp_spki matches Root CA \"$ca_cn\" pinned. (Root CA part of the chain)" - else # not part of chain - match_ca="" - has_backup_spki=true # Root CA outside the chain --> we save it for unmatched - fileout "HPKP_$hpkp_spki" "INFO" "SPKI $hpkp_spki matches Root CA \"$ca_cn\" pinned. (Root backup SPKI)" - backup_spki[i]="$(strip_lf "$hpkp_spki")" # save it for later - backup_spki_str[i]="$ca_cn" # also the name=CN of the root CA - i=$((i + 1)) - fi - fi - fi - - # still no success --> it's probably a backup SPKI - if ! "$certificate_found"; then - # Most likely a backup SPKI, unfortunately we can't tell for what it is: host, intermediates - has_backup_spki=true - backup_spki[i]="$(strip_lf "$hpkp_spki")" # save it for later - backup_spki_str[i]="" # no root ca - i=$((i + 1)) - fileout "HPKP_$hpkp_spki" "INFO" "SPKI $hpkp_spki doesn't match anything. This is ok for a backup for any certificate" - # CSV/JSON output here for the sake of simplicity, rest we do en bloc below - fi - done - - # now print every backup spki out we saved before - out "\n$spaces_indented Backups: " - - # for i=0 manually do the same as below as there's other indentation here - if [[ -n "${backup_spki_str[0]}" ]]; then - pr_svrty_good "${backup_spki[0]}" - #out " Root CA: " - prln_italic " ${backup_spki_str[0]}" - else - outln "${backup_spki[0]}" - fi - # now for i=1 - for ((i=1; i < ${#backup_spki[@]} ;i++ )); do - if [[ -n "${backup_spki_str[i]}" ]]; then - # it's a Root CA outside the chain - pr_svrty_good "$spaces_indented ${backup_spki[i]}" - #out " Root CA: " - prln_italic " ${backup_spki_str[i]}" - else - outln "$spaces_indented ${backup_spki[i]}" - fi - done - if [[ ! -f "$ca_hashes" ]] && "$spki_match"; then - out "$spaces " - prln_warning "Attribution of further hashes couldn't be done as $ca_hashes could not be found" - fileout "HPKP_SPKImatch" "WARN" "Attribution of further hashes possible as $ca_hashes could not be found" - fi - - # If all else fails... - if ! "$spki_match"; then - "$has_backup_spki" && out "$spaces" # we had a few lines with backup SPKIs already - prln_svrty_high " No matching key for SPKI found " - fileout "HPKP_SPKImatch" "HIGH" "None of the SPKI match your host certificate, intermediate CA or known root CAs. Bricked site?" - set_grade_cap "A" "Problems with HTTP Public Key Pinning (HPKP)" - fi - - if ! "$has_backup_spki"; then - prln_svrty_high " No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site. " - fileout "HPKP_backup" "HIGH" "No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site." - set_grade_cap "A" "Problems with HTTP Public Key Pinning (HPKP)" - fi - else - outln "--" - fileout "HPKP" "INFO" "No support for HTTP Public Key Pinning" - fi - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - -emphasize_stuff_in_headers(){ - local html_brown="" - local html_yellow="" - local html_off="<\\/span>" - -# see https://www.grymoire.com/Unix/Sed.html#uh-3 -# outln "$1" | sed "s/[0-9]*/$brown&${off}/g" - tmln_out "$1" | sed -e "s/\([0-9]\)/${brown}\1${off}/g" \ - -e "s/Unix/${yellow}Unix${off}/g" \ - -e "s/Debian/${yellow}Debian${off}/g" \ - -e "s/Win32/${yellow}Win32${off}/g" \ - -e "s/Win64/${yellow}Win64${off}/g" \ - -e "s/Ubuntu/${yellow}Ubuntu${off}/g" \ - -e "s/ubuntu/${yellow}ubuntu${off}/g" \ - -e "s/buster/${yellow}buster${off}/g" \ - -e "s/stretch/${yellow}stretch${off}/g" \ - -e "s/jessie/${yellow}jessie${off}/g" \ - -e "s/squeeze/${yellow}squeeze${off}/g" \ - -e "s/wheezy/${yellow}wheezy${off}/g" \ - -e "s/lenny/${yellow}lenny${off}/g" \ - -e "s/SUSE/${yellow}SUSE${off}/g" \ - -e "s/Red Hat Enterprise Linux/${yellow}Red Hat Enterprise Linux${off}/g" \ - -e "s/Red Hat/${yellow}Red Hat${off}/g" \ - -e "s/CentOS/${yellow}CentOS${off}/g" \ - -e "s/Via/${yellow}Via${off}/g" \ - -e "s/X-Forwarded/${yellow}X-Forwarded${off}/g" \ - -e "s/X-TYPO3-Parsetime/${yellow}X-TYPO3-Parsetime${off}/g" \ - -e "s/Liferay-Portal/${yellow}Liferay-Portal${off}/g" \ - -e "s/X-Cache-Lookup/${yellow}X-Cache-Lookup${off}/g" \ - -e "s/X-Cache/${yellow}X-Cache${off}/g" \ - -e "s/X-Squid/${yellow}X-Squid${off}/g" \ - -e "s/X-Server/${yellow}X-Server${off}/g" \ - -e "s/X-Varnish/${yellow}X-Varnish${off}/g" \ - -e "s/X-OWA-Version/${yellow}X-OWA-Version${off}/g" \ - -e "s/MicrosoftSharePointTeamServices/${yellow}MicrosoftSharePointTeamServices${off}/g" \ - -e "s/X-Application-Context/${yellow}X-Application-Context${off}/g" \ - -e "s/X-Version/${yellow}X-Version${off}/g" \ - -e "s/X-Powered-By/${yellow}X-Powered-By${off}/g" \ - -e "s/X-UA-Compatible/${yellow}X-UA-Compatible${off}/g" \ - -e "s/Link/${yellow}Link${off}/g" \ - -e "s/X-Rack-Cache/${yellow}X-Rack-Cache${off}/g" \ - -e "s/X-Runtime/${yellow}X-Runtime${off}/g" \ - -e "s/X-Pingback/${yellow}X-Pingback${off}/g" \ - -e "s/X-Permitted-Cross-Domain-Policies/${yellow}X-Permitted-Cross-Domain-Policies${off}/g" \ - -e "s/X-AspNet-Version/${yellow}X-AspNet-Version${off}/g" \ - -e "s/x-note/${yellow}x-note${off}/g" \ - -e "s/x-global-transaction-id/${yellow}x-global-transaction-id${off}/g" \ - -e "s/X-Global-Transaction-ID/${yellow}X-Global-Transaction-ID${off}/g" \ - -e "s/Alt-Svc/${yellow}Alt-Svc${off}/g" \ - -e "s/system-wsgw-management-loopback/${yellow}system-wsgw-management-loopback${off}/g" - - if "$do_html"; then - if [[ $COLOR -ge 2 ]]; then - html_out "$(tm_out "$1" | sed -e 's/\&/\&/g' \ - -e 's//\>/g' -e 's/"/\"/g' -e "s/'/\'/g" \ - -e "s/\([0-9]\)/${html_brown}\1${html_off}/g" \ - -e "s/Unix/${html_yellow}Unix${html_off}/g" \ - -e "s/Debian/${html_yellow}Debian${html_off}/g" \ - -e "s/Win32/${html_yellow}Win32${html_off}/g" \ - -e "s/Win64/${html_yellow}Win64${html_off}/g" \ - -e "s/Ubuntu/${html_yellow}Ubuntu${html_off}/g" \ - -e "s/ubuntu/${html_yellow}ubuntu${html_off}/g" \ - -e "s/buster/${html_yellow}buster${html_off}/g" \ - -e "s/stretch/${html_yellow}stretch${html_off}/g" \ - -e "s/jessie/${html_yellow}jessie${html_off}/g" \ - -e "s/squeeze/${html_yellow}squeeze${html_off}/g" \ - -e "s/wheezy/${html_yellow}wheezy${html_off}/g" \ - -e "s/lenny/${html_yellow}lenny${html_off}/g" \ - -e "s/SUSE/${html_yellow}SUSE${html_off}/g" \ - -e "s/Red Hat Enterprise Linux/${html_yellow}Red Hat Enterprise Linux${html_off}/g" \ - -e "s/Red Hat/${html_yellow}Red Hat${html_off}/g" \ - -e "s/CentOS/${html_yellow}CentOS${html_off}/g" \ - -e "s/Via/${html_yellow}Via${html_off}/g" \ - -e "s/X-Forwarded/${html_yellow}X-Forwarded${html_off}/g" \ - -e "s/X-TYPO3-Parsetime/${yellow}X-TYPO3-Parsetime${html_off}/g" \ - -e "s/Liferay-Portal/${html_yellow}Liferay-Portal${html_off}/g" \ - -e "s/X-Cache-Lookup/${html_yellow}X-Cache-Lookup${html_off}/g" \ - -e "s/X-Cache/${html_yellow}X-Cache${html_off}/g" \ - -e "s/X-Squid/${html_yellow}X-Squid${html_off}/g" \ - -e "s/X-Server/${html_yellow}X-Server${html_off}/g" \ - -e "s/X-Varnish/${html_yellow}X-Varnish${html_off}/g" \ - -e "s/X-OWA-Version/${html_yellow}X-OWA-Version${html_off}/g" \ - -e "s/MicrosoftSharePointTeamServices/${html_yellow}MicrosoftSharePointTeamServices${html_off}/g" \ - -e "s/X-Application-Context/${html_yellow}X-Application-Context${html_off}/g" \ - -e "s/X-Version/${html_yellow}X-Version${html_off}/g" \ - -e "s/X-Powered-By/${html_yellow}X-Powered-By${html_off}/g" \ - -e "s/X-UA-Compatible/${html_yellow}X-UA-Compatible${html_off}/g" \ - -e "s/Link/${html_yellow}Link${html_off}/g" \ - -e "s/X-Runtime/${html_yellow}X-Runtime${html_off}/g" \ - -e "s/X-Rack-Cache/${html_yellow}X-Rack-Cache${html_off}/g" \ - -e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \ - -e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \ - -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \ - -e "s/x-note/${html_yellow}x-note${html_off}/g" \ - -e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \ - -e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \ - -e "s/Alt-Svc/${html_yellow}Alt-Svc${html_off}/g" \ - -e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g" -#FIXME: this is double code. The pattern to emphasize would fit better into -# one function. -# Also we need another function like run_other_header as otherwise "Link" "Alt-Svc" will never be found. -# And: I matches case sensitive only which might not detect all banners. (sed ignorecase is not possible w/ BSD sed) - else - html_out "$(html_reserved "$1")" - fi - html_out "\n" - fi -} - -run_server_banner() { - local serverbanner - local jsonID="banner_server" - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - pr_bold " Server banner " - grep -ai '^Server' $HEADERFILE >$TMPFILE - if [[ $? -eq 0 ]]; then - serverbanner=$(sed -e 's/^Server: //' -e 's/^server: //' $TMPFILE) - serverbanner=${serverbanner//$'\r'} - serverbanner=${serverbanner//$'\n'} - if [[ -z "$serverbanner" ]]; then - outln "exists but empty string" - fileout "$jsonID" "INFO" "Server banner is empty" - else - emphasize_stuff_in_headers "$serverbanner" - fileout "$jsonID" "INFO" "$serverbanner" - if [[ "$serverbanner" == *Microsoft-IIS/6.* ]] && [[ $OSSL_VER == 1.0.2* ]]; then - prln_warning " It's recommended to run another test w/ OpenSSL >= 1.0.1 !" - # see https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892 - fileout "${jsonID}" "WARN" "IIS6_openssl_mismatch: Recommended to rerun this test w/ OpenSSL >= 1.0.1. See https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892" - fi - fi - # mozilla.github.io/server-side-tls/ssl-config-generator/ - # https://support.microsoft.com/en-us/kb/245030 - else - outln "(no \"Server\" line in header, interesting!)" - fileout "$jsonID" "INFO" "No Server banner line in header, interesting!" - fi - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - -run_appl_banner() { - local line - local first=true - local spaces=" " - local appl_banners="" - local jsonID="banner_application" - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - pr_bold " Application banner " - grep -Eai '^X-Powered-By|^X-AspNet-Version|^X-Version|^Liferay-Portal|^X-TYPO3-Parsetime|^X-OWA-Version^|^MicrosoftSharePointTeamServices' $HEADERFILE >$TMPFILE - if [[ $? -ne 0 ]]; then - outln "--" - fileout "$jsonID" "INFO" "No application banner found" - else - while IFS='' read -r line; do - line=$(strip_lf "$line") - if ! $first; then - out "$spaces" - appl_banners="${appl_banners}, ${line}" - else - appl_banners="${line}" - first=false - fi - emphasize_stuff_in_headers "$line" - done < "$TMPFILE" - fileout "$jsonID" "INFO" "$appl_banners" - fi - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - -run_rp_banner() { - local line - local first=true - local spaces=" " - local rp_banners="" - local jsonID="banner_reverseproxy" - local cwe="CWE-200" - local cve="" - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - pr_bold " Reverse Proxy banner " - grep -Eai '^Via:|^X-Cache|^X-Squid|^X-Varnish:|^X-Server-Name:|^X-Server-Port:|^x-forwarded|^Forwarded' $HEADERFILE >$TMPFILE - if [[ $? -ne 0 ]]; then - outln "--" - fileout "$jsonID" "INFO" "--" "$cve" "$cwe" - else - while read line; do - line=$(strip_lf "$line") - if $first; then - first=false - else - out "$spaces" - fi - emphasize_stuff_in_headers "$line" - rp_banners="${rp_banners}${line}" - done < $TMPFILE - fileout "$jsonID" "INFO" "$rp_banners" "$cve" "$cwe" - fi - outln - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - - -# arg1: multiline string w cookies -# -sub_f5_bigip_check() { - local allcookies="$1" - local ip port cookievalue cookiename - local routed_domain offset - local savedcookies="" - local spaces="$2" - local cwe="CWE-212" - local cve="" - - # taken from https://github.com/drwetter/F5-BIGIP-Decoder, more details see there - - debugme echo -e "all cookies: >> $allcookies <<\n" - while true; do IFS='=' read cookiename cookievalue - [[ -z "$cookievalue" ]] && break - cookievalue=${cookievalue/;/} - debugme echo $cookiename : $cookievalue - if grep -Eq '[0-9]{9,10}\.[0-9]{3,5}\.0000' <<< "$cookievalue"; then - ip="$(f5_ip_oldstyle "$cookievalue")" - port="$(f5_port_decode $cookievalue)" - out "${spaces}F5 cookie (default IPv4 pool member): "; pr_italic "$cookiename "; prln_svrty_medium "${ip}:${port}" - fileout "cookie_bigip_f5" "MEDIUM" "Information leakage: F5 cookie $cookiename $cookievalue is default IPv4 pool member ${ip}:${port}" "$cve" "$cwe" - elif grep -Eq '^rd[0-9]{1,3}o0{20}f{4}[a-f0-9]{8}o[0-9]{1,5}' <<< "$cookievalue"; then - routed_domain="$(f5_determine_routeddomain "$cookievalue")" - offset=$(( 2 + ${#routed_domain} + 1 + 24)) - port="${cookievalue##*o}" - ip="$(f5_hex2ip "${cookievalue:$offset:8}")" - out "${spaces}F5 cookie (IPv4 pool in routed domain "; pr_svrty_medium "$routed_domain"; out "): "; pr_italic "$cookiename "; prln_svrty_medium "${ip}:${port}" - fileout "cookie_bigip_f5" "MEDIUM" "Information leakage: F5 cookie $cookiename $cookievalue is IPv4 pool member in routed domain $routed_domain ${ip}:${port}" "$cve" "$cwe" - elif grep -Eq '^vi[a-f0-9]{32}\.[0-9]{1,5}' <<< "$cookievalue"; then - ip="$(f5_hex2ip6 ${cookievalue:2:32})" - port="${cookievalue##*.}" - port=$(f5_port_decode "$port") - out "${spaces}F5 cookie (default IPv6 pool member): "; pr_italic "$cookiename "; prln_svrty_medium "${ip}:${port}" - fileout "cookie_bigip_f5" "MEDIUM" "Information leakage: F5 cookie $cookiename $cookievalue is default IPv6 pool member ${ip}:${port}" "$cve" "$cwe" - elif grep -Eq '^rd[0-9]{1,3}o[a-f0-9]{32}o[0-9]{1,5}' <<< "$cookievalue"; then - routed_domain="$(f5_determine_routeddomain "$cookievalue")" - offset=$(( 2 + ${#routed_domain} + 1 )) - port="${cookievalue##*o}" - ip="$(f5_hex2ip6 ${cookievalue:$offset:32})" - out "${spaces}F5 cookie (IPv6 pool in routed domain "; pr_svrty_medium "$routed_domain"; out "): "; pr_italic "$cookiename "; prln_svrty_medium "${ip}:${port}" - fileout "cookie_bigip_f5" "MEDIUM" "Information leakage: F5 cookie $cookiename $cookievalue is IPv6 pool member in routed domain $routed_domain ${ip}:${port}" "$cve" "$cwe" - elif grep -Eq '^\!.*=$' <<< "$cookievalue"; then - if [[ "${#cookievalue}" -eq 81 ]] ; then - savedcookies="${savedcookies} ${cookiename}=${cookievalue:1:79}" - out "${spaces}Encrypted F5 cookie named "; pr_italic "${cookiename}"; outln " detected" - fileout "cookie_bigip_f5" "INFO" "encrypted F5 cookie named ${cookiename}" - fi - fi - done <<< "$allcookies" -} - - -run_cookie_flags() { # ARG1: Path - local -i nr_cookies - local -i nr_httponly nr_secure - local negative_word - local msg302="" msg302_="" - local spaces=" " - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - - if [[ ! "$HTTP_STATUS_CODE" =~ 20 ]]; then - if [[ "$HTTP_STATUS_CODE" =~ [301|302] ]]; then - msg302=" -- maybe better try target URL of 30x" - msg302_=" (30x detected, better try target URL of 30x)" - else - msg302=" -- HTTP status $HTTP_STATUS_CODE signals you maybe missed the web application" - msg302_=" (maybe missed the application)" - fi - fi - - pr_bold " Cookie(s) " - grep -ai '^Set-Cookie' $HEADERFILE >$TMPFILE - if [[ $? -ne 0 ]]; then - outln "(none issued at \"$1\")$msg302" - fileout "cookie_count" "INFO" "0 at \"$1\"$msg302_" - else - nr_cookies=$(count_lines "$(cat $TMPFILE)") - out "$nr_cookies issued: " - fileout "cookie_count" "INFO" "$nr_cookies at \"$1\"$msg302_" - if [[ $nr_cookies -gt 1 ]]; then - negative_word="NONE" - else - negative_word="NOT" - fi - nr_secure=$(grep -iac secure $TMPFILE) - case $nr_secure in - 0) pr_svrty_medium "$negative_word" ;; - [123456789]) pr_svrty_good "$nr_secure/$nr_cookies";; - esac - out " secure, " - if [[ $nr_cookies -eq $nr_secure ]]; then - fileout "cookie_secure" "OK" "All ($nr_cookies) at \"$1\" marked as secure" - else - fileout "cookie_secure" "INFO" "$nr_secure/$nr_cookies at \"$1\" marked as secure" - fi - nr_httponly=$(grep -cai httponly $TMPFILE) - case $nr_httponly in - 0) pr_svrty_medium "$negative_word" ;; - [123456789]) pr_svrty_good "$nr_httponly/$nr_cookies";; - esac - out " HttpOnly" - if [[ $nr_cookies -eq $nr_httponly ]]; then - fileout "cookie_httponly" "OK" "All ($nr_cookies) at \"$1\" marked as HttpOnly$msg302_" - else - fileout "cookie_httponly" "INFO" "$nr_secure/$nr_cookies at \"$1\" marked as HttpOnly$msg302_" - fi - outln "$msg302" - allcookies="$(awk '/[Ss][Ee][Tt]-[Cc][Oo][Oo][Kk][Ii][Ee]:/ { print $2 }' "$TMPFILE")" - sub_f5_bigip_check "$allcookies" "$spaces" - fi - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - - -run_security_headers() { - local header header_output svrty header_and_svrty - local first=true - local spaces=" " - local have_header=false - - if [[ ! -s $HEADERFILE ]]; then - run_http_header "$1" || return 1 - fi - - pr_bold " Security headers " - # X-XSS-Protection is useless and at worst harmful, see https://news.ycombinator.com/item?id=20472947 - for header_and_svrty in "X-Frame-Options OK" \ - "X-Content-Type-Options OK" \ - "Content-Security-Policy OK" \ - "X-Content-Security-Policy OK" \ - "X-WebKit-CSP OK" \ - "Content-Security-Policy-Report-Only OK" \ - "Expect-CT OK" \ - "Permissions-Policy OK" \ - "X-XSS-Protection INFO" \ - "Access-Control-Allow-Origin INFO" \ - "Upgrade INFO" \ - "X-Served-By INFO" \ - "Referrer-Policy INFO" \ - "X-UA-Compatible INFO" \ - "Cache-Control INFO" \ - "Pragma INFO"; do - read header svrty <<< "${header_and_svrty}" - [[ "$DEBUG" -ge 5 ]] && echo "testing \"$header\" (severity \"$svrty\")" - match_httpheader_key "$header" "$header" "$spaces" "$first" - if [[ $? -ge 1 ]]; then - have_header=true - if "$first"; then - first=false - fi - case "$svrty" in - OK) pr_svrty_good "$header" ;; - LOW) pr_svrty_low "$header" ;; - INFO) out "$header" ;; - esac - # Include $header when determining where to insert line breaks, but print $header - # separately. - header_output="$(out_row_aligned_max_width "${header:2}: $HEADERVALUE" "$spaces " $TERM_WIDTH)" - outln "${header_output#${header:2}}" - fileout "$header" "$svrty" "$HEADERVALUE" - fi - done - - #TODO: I am not testing for the correctness or anything stupid yet, e.g. "X-Frame-Options: allowall" or Access-Control-Allow-Origin: * - - if ! "$have_header"; then - prln_svrty_medium "--" - fileout "security_headers" "MEDIUM" "--" - fi - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - - -# #1: string with 2 openssl codes, output is same in NSS/ssllabs terminology -normalize_ciphercode() { - if [[ "${1:2:2}" == "00" ]]; then - tm_out "$(tolower "x${1:7:2}")" - else - tm_out "$(tolower "x${1:2:2}${1:7:2}${1:12:2}")" - fi - return 0 -} - -prettyprint_local() { - local arg line - local hexc hexcode dash ciph sslvers kx auth enc mac export - local re='^[0-9A-Fa-f]+$' - - if [[ "$1" == 0x* ]] || [[ "$1" == 0X* ]]; then - fatal "pls supply x instead" $ERR_CMDLINE - fi - - if [[ -z "$1" ]]; then - pr_headline " Displaying all $OPENSSL_NR_CIPHERS local ciphers "; - else - pr_headline " Displaying all local ciphers "; - # pattern provided; which one? - [[ $1 =~ $re ]] && \ - pr_headline "matching number pattern \"$1\" " || \ - pr_headline "matching word pattern "\"$1\"" (ignore case) " - fi - outln "\n" - neat_header - - if [[ -z "$1" ]]; then - while read -r hexcode dash ciph sslvers kx auth enc mac export ; do - hexc="$(normalize_ciphercode $hexcode)" - outln "$(neat_list "$hexc" "$ciph" "$kx" "$enc" "$export")" - done < <(actually_supported_osslciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 'ALL' "-V") # -V doesn't work with openssl < 1.0 - else - #for arg in $(echo $@ | sed 's/,/ /g'); do - for arg in ${*//,/ /}; do - while read -r hexcode dash ciph sslvers kx auth enc mac export ; do - hexc="$(normalize_ciphercode $hexcode)" - # for numbers we don't do word matching: - [[ $arg =~ $re ]] && \ - line="$(neat_list "$hexc" "$ciph" "$kx" "$enc" "$export" | grep -ai "$arg")" || \ - line="$(neat_list "$hexc" "$ciph" "$kx" "$enc" "$export" | grep -wai "$arg")" - [[ -n "$line" ]] && outln "$line" - done < <(actually_supported_osslciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 'ALL' "-V") # -V doesn't work with openssl < 1.0 - done - fi - outln - return 0 -} - - -# Generic function for a rated output, no used yet. -# arg1: rating from 2 to -4 if available or not -# arg2: no/yes: decides whether positive or negative logic will be applied and "not" will be printed -# arg3: jsonID -# -rated_output() { - local jsonID=$3 - local logic="" - - if [[ $2 == no ]] || [[ $2 == negative ]]; then - logic="not " - fi - case $1 in - 2) pr_svrty_best "${logic}offered (OK)" - fileout "${jsonID}" "OK" "${logic}offered" - ;; - 1) pr_svrty_good "${logic}offered (OK)" - fileout "${jsonID}" "OK" "${logic}offered" - ;; - 0) out "${logic}offered" - fileout "${jsonID}" "INFO" "${logic}offered" - ;; - -1) pr_svrty_low "${logic}offered" - fileout "${jsonID}" "LOW" "${logic}offered" - ;; - -2) pr_svrty_medium "${logic}offered" - fileout "${jsonID}" "MEDIUM" "${logic}offered" - ;; - -3) pr_svrty_high "${logic}offered (NOT ok)" - fileout "${jsonID}" "HIGH" "${logic}offered" - ;; - -4) pr_svrty_critical "${logic}offered (NOT ok)" - fileout "${jsonID}" "CRITICAL" "${logic}offered" - ;; - *) pr_warning "FIXME: error around $LINENO, (please report this)" - fileout "${jsonID}" "WARN" "return condition $2 when $1 unclear" - return 1 - ;; - esac - return 0 -} - - -openssl2rfc() { - local rfcname="" - local -i i - - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$1" == ${TLS_CIPHER_OSSL_NAME[i]} ]] && rfcname="${TLS_CIPHER_RFC_NAME[i]}" && break - done - [[ "$rfcname" == "-" ]] && rfcname="" - [[ -n "$rfcname" ]] && tm_out "$rfcname" - return 0 -} - -rfc2openssl() { - local ossl_name - local -i i - - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$1" == ${TLS_CIPHER_RFC_NAME[i]} ]] && ossl_name="${TLS_CIPHER_OSSL_NAME[i]}" && break - done - [[ "$ossl_name" == "-" ]] && ossl_name="" - [[ -n "$ossl_name" ]] && tm_out "$ossl_name" - return 0 -} - -openssl2hexcode() { - local hexc="" - local -i i - - if [[ $TLS_NR_CIPHERS -eq 0 ]]; then - if "$HAS_CIPHERSUITES"; then - hexc="$($OPENSSL ciphers -V -ciphersuites "$TLS13_OSSL_CIPHERS" 'ALL:COMPLEMENTOFALL:@STRENGTH' | awk '/ '"$1"' / { print $1 }')" - elif "$HAS_SSL2"; then - hexc="$($OPENSSL ciphers -V -tls1 'ALL:COMPLEMENTOFALL:@STRENGTH' | awk '/ '"$1"' / { print $1 }')" - else - hexc="$($OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' | awk '/ '"$1"' / { print $1 }')" - fi - else - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$1" == ${TLS_CIPHER_OSSL_NAME[i]} ]] && hexc="${TLS_CIPHER_HEXCODE[i]}" && break - done - fi - [[ -z "$hexc" ]] && return 1 - tm_out "$hexc" - return 0 -} - -rfc2hexcode() { - local hexc="" - local -i i - - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$1" == ${TLS_CIPHER_RFC_NAME[i]} ]] && hexc="${TLS_CIPHER_HEXCODE[i]}" && break - done - [[ -z "$hexc" ]] && return 1 - tm_out "$hexc" - return 0 -} - -show_rfc_style(){ - local rfcname="" hexcode - local -i i - - hexcode="$(toupper "$1")" - case ${#hexcode} in - 3) hexcode="0x00,0x${hexcode:1:2}" ;; - 5) hexcode="0x${hexcode:1:2},0x${hexcode:3:2}" ;; - 7) hexcode="0x${hexcode:1:2},0x${hexcode:3:2},0x${hexcode:5:2}" ;; - *) return 1 ;; - esac - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$hexcode" == ${TLS_CIPHER_HEXCODE[i]} ]] && rfcname="${TLS_CIPHER_RFC_NAME[i]}" && break - done - [[ "$rfcname" == "-" ]] && rfcname="" - [[ -n "$rfcname" ]] && tm_out "$rfcname" - return 0 -} - -neat_header(){ - if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then - out "$(printf -- "Hexcode Cipher Suite Name (IANA/RFC) KeyExch. Encryption Bits")" - [[ "$DISPLAY_CIPHERNAMES" != rfc-only ]] && out "$(printf -- " Cipher Suite Name (OpenSSL)")" - outln - out "$(printf -- "%s------------------------------------------------------------------------------------------")" - [[ "$DISPLAY_CIPHERNAMES" != rfc-only ]] && out "$(printf -- "---------------------------------------")" - outln - else - out "$(printf -- "Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits")" - [[ "$DISPLAY_CIPHERNAMES" != openssl-only ]] && out "$(printf -- " Cipher Suite Name (IANA/RFC)")" - outln - out "$(printf -- "%s--------------------------------------------------------------------------")" - [[ "$DISPLAY_CIPHERNAMES" != openssl-only ]] && out "$(printf -- "---------------------------------------------------")" - outln - fi -} - - -# arg1: hexcode -# arg2: cipher in openssl notation -# arg3: keyexchange -# arg4: encryption (maybe included "export") -# arg5: "export" if the cipher is an export-quality cipher, empty otherwise. -# arg6: not a boolean! -# "true" : if the cipher's "quality" should be highlighted -# "false": if the line should be printed in light grey -# "" : if line should be returned as a string - -neat_list(){ - local hexcode="$1" - local ossl_cipher="$2" export="$5" tls_cipher="" - local kx enc strength line what_dh bits - local -i i len - local how2show="$6" - - kx="${3//Kx=/}" - kx="$(strip_trailing_space "$kx")" - enc="${4//Enc=/}" - # In two cases LibreSSL uses very long names for encryption algorithms - # and doesn't include the number of bits. - [[ "$enc" == ChaCha20-Poly1305 ]] && enc="CHACHA20(256)" - [[ "$enc" == GOST-28178-89-CNT ]] && enc="GOST(256)" - - strength="${enc//\)/}" # retrieve (). first remove trailing ")" - strength="${strength#*\(}" # exfiltrate (VAL - enc="${enc%%\(*}" - - enc="${enc//POLY1305/}" # remove POLY1305 - enc="${enc//\//}" # remove "/" - - # For rating set bit size but only when cipher is supported by server. - if [[ $how2show == true ]]; then - set_ciph_str_score $strength - fi - - [[ "$export" =~ export ]] && strength="$strength,exp" - - [[ "$DISPLAY_CIPHERNAMES" != openssl-only ]] && tls_cipher="$(show_rfc_style "$hexcode")" - - # global var SHOW_EACH_C determines whether we display all tested ciphers - if [[ "$how2show" != true ]]; then - if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then - line="$(printf -- " %-7s %-49s %-10s %-12s%-8s" "$hexcode" "$tls_cipher" "$kx" "$enc" "$strength")" - [[ "$DISPLAY_CIPHERNAMES" != rfc-only ]] && line+="$(printf -- " %-33s${SHOW_EACH_C:+ %-0s}" "$ossl_cipher")" - else - line="$(printf -- " %-7s %-33s %-10s %-12s%-8s" "$hexcode" "$ossl_cipher" "$kx" "$enc" "$strength")" - [[ "$DISPLAY_CIPHERNAMES" != openssl-only ]] && line+="$(printf -- " %-49s${SHOW_EACH_C:+ %-0s}" "$tls_cipher")" - fi - if [[ -z "$how2show" ]]; then - tm_out "$line" - else - pr_deemphasize "$line" - fi - return 0 - fi - if [[ "$kx" =~ " " ]]; then - what_dh="${kx%% *}" - bits="${kx##* }" - else - what_dh="$kx" - bits="" - fi - if [[ "$COLOR" -le 2 ]]; then - if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then - out "$(printf -- " %-7s %-49s " "$hexcode" "$tls_cipher")" - else - out "$(printf -- " %-7s %-33s " "$hexcode" "$ossl_cipher")" - fi - else - out "$(printf -- " %-7s " "$hexcode")" - if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then - print_fixed_width "$tls_cipher" 49 pr_cipher_quality - else - print_fixed_width "$ossl_cipher" 33 pr_cipher_quality - fi - fi - out "$what_dh" - if [[ -n "$bits" ]]; then - if [[ $what_dh == DH ]] || [[ $what_dh == EDH ]]; then - pr_dh_quality "$bits" " $bits" - elif [[ $what_dh == ECDH ]]; then - pr_ecdh_quality "$bits" " $bits" - fi - fi - len=${#kx} - print_n_spaces "$((10-len))" - out "$(printf -- " %-12s%-8s " "$enc" "$strength")" - if [[ "$COLOR" -le 2 ]]; then - if [[ "$DISPLAY_CIPHERNAMES" == rfc ]]; then - out "$(printf -- "%-33s${SHOW_EACH_C:+ %-0s}" "$ossl_cipher")" - elif [[ "$DISPLAY_CIPHERNAMES" == openssl ]]; then - out "$(printf -- "%-49s${SHOW_EACH_C:+ %-0s}" "$tls_cipher")" - fi - else - if [[ "$DISPLAY_CIPHERNAMES" == rfc ]]; then - print_fixed_width "$ossl_cipher" 32 pr_cipher_quality - elif [[ "$DISPLAY_CIPHERNAMES" == openssl ]]; then - print_fixed_width "$tls_cipher" 48 pr_cipher_quality - fi - out "$(printf -- "${SHOW_EACH_C:+ %-0s}")" - fi -} - -run_cipher_match(){ - local hexc n auth ciphers_to_test tls13_ciphers_to_test supported_sslv2_ciphers s - local -a hexcode normalized_hexcode ciph sslvers kx enc export2 sigalg - local -a ciphers_found ciphers_found2 ciph2 rfc_ciph rfc_ciph2 ossl_supported - local -a -i index - local -i nr_ciphers=0 nr_ossl_ciphers=0 nr_nonossl_ciphers=0 - local -i num_bundles bundle_size bundle end_of_bundle - local dhlen has_dh_bits="$HAS_DH_BITS" - local cipher proto protos_to_try - local available - local -i sclient_success - local re='^[0-9A-Fa-f]+$' - local using_sockets=true - - "$SSL_NATIVE" && using_sockets=false - "$FAST" && using_sockets=false - [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false - - pr_headline " Testing ciphers with " - if [[ $1 =~ $re ]]; then - pr_headline "matching number pattern \"$1\" " - tjolines="$tjolines matching number pattern \"$1\"\n\n" - else - pr_headline "word pattern "\"$1\"" (ignore case) " - tjolines="$tjolines word pattern \"$1\" (ignore case)\n\n" - fi - outln - if ! "$using_sockets"; then - [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" - if ! "$HAS_DH_BITS"; then - [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." - prln_warning " (Your $OPENSSL cannot show DH/ECDH bits)" - fi - fi - outln - neat_header - #for arg in $(echo $@ | sed 's/,/ /g'); do - for arg in ${*//, /}; do - if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - hexc="${TLS_CIPHER_HEXCODE[i]}" - if [[ ${#hexc} -eq 9 ]]; then - hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" - if [[ "${hexc:2:2}" == 00 ]]; then - normalized_hexcode[nr_ciphers]="x${hexc:7:2}" - else - normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" - fi - else - hexc="$(tolower "$hexc")" - hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2},${hexc:12:2}" - normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}${hexc:12:2}" - fi - if [[ $arg =~ $re ]]; then - neat_list "${normalized_hexcode[nr_ciphers]}" "${TLS_CIPHER_OSSL_NAME[i]}" "${TLS_CIPHER_KX[i]}" "${TLS_CIPHER_ENC[i]}" "${TLS_CIPHER_EXPORT[i]}" | grep -qai "$arg" - else - neat_list "${normalized_hexcode[nr_ciphers]}" "${TLS_CIPHER_OSSL_NAME[i]}" "${TLS_CIPHER_KX[i]}" "${TLS_CIPHER_ENC[i]}" "${TLS_CIPHER_EXPORT[i]}" | grep -qwai "$arg" - fi - if [[ $? -eq 0 ]] && { "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}"; }; then # string matches, so we can ssl to it: - normalized_hexcode[nr_ciphers]="$(tolower "${normalized_hexcode[nr_ciphers]}")" - ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" - rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" - kx[nr_ciphers]="${TLS_CIPHER_KX[i]}" - enc[nr_ciphers]="${TLS_CIPHER_ENC[i]}" - sslvers[nr_ciphers]="${TLS_CIPHER_SSLVERS[i]}" - export2[nr_ciphers]="${TLS_CIPHER_EXPORT[i]}" - ciphers_found[nr_ciphers]=false - sigalg[nr_ciphers]="" - ossl_supported[nr_ciphers]="${TLS_CIPHER_OSSL_SUPPORTED[i]}" - if "$using_sockets" && ! "$has_dh_bits" && \ - [[ ${kx[nr_ciphers]} == "Kx=ECDH" || ${kx[nr_ciphers]} == "Kx=DH" || ${kx[nr_ciphers]} == "Kx=EDH" ]]; then - ossl_supported[nr_ciphers]=false - fi - nr_ciphers+=1 - fi - done - else - while read hexc n ciph[nr_ciphers] sslvers[nr_ciphers] kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do - hexc="$(normalize_ciphercode $hexc)" - # is argument a number? - if [[ $arg =~ $re ]]; then - neat_list "$hexc" "${ciph[nr_ciphers]}" "${kx[nr_ciphers]}" "${enc[nr_ciphers]}" "${export2[nr_ciphers]}" | grep -qai "$arg" - else - neat_list "$hexc" "${ciph[nr_ciphers]}" "${kx[nr_ciphers]}" "${enc[nr_ciphers]}" "${export2[nr_ciphers]}" | grep -qwai "$arg" - fi - if [[ $? -eq 0 ]]; then # string matches, so we can ssl to it: - ciphers_found[nr_ciphers]=false - normalized_hexcode[nr_ciphers]="$hexc" - sigalg[nr_ciphers]="" - ossl_supported[nr_ciphers]=true - nr_ciphers+=1 - fi - done < <(actually_supported_osslciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 'ALL' "-V") - fi - - # Test the SSLv2 ciphers, if any. - if "$using_sockets"; then - ciphers_to_test="" - for (( i=0; i < nr_ciphers; i++ )); do - if [[ "${sslvers[i]}" == SSLv2 ]]; then - ciphers_to_test+=", ${hexcode[i]}" - fi - done - if [[ -n "$ciphers_to_test" ]]; then - sslv2_sockets "${ciphers_to_test:2}" "true" - if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then - supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" - "$SHOW_SIGALGO" && s="$(read_sigalg_from_file "$HOSTCERT")" - for (( i=0 ; i$TMPFILE 2>$ERRFILE = 128 ciphers. So, - # test cipher suites in bundles of 128 or less. - num_bundles=$nr_ossl_ciphers/128 - [[ $((nr_ossl_ciphers%128)) -ne 0 ]] && num_bundles+=1 - - bundle_size=$nr_ossl_ciphers/$num_bundles - [[ $((nr_ossl_ciphers%num_bundles)) -ne 0 ]] && bundle_size+=1 - fi - - if "$HAS_TLS13"; then - protos_to_try="-no_ssl2 -tls1_2 -tls1_1 -tls1" - else - protos_to_try="-no_ssl2 -tls1_1 -tls1" - fi - "$HAS_SSL3" && protos_to_try+=" -ssl3" - - for proto in $protos_to_try; do - if [[ "$proto" == -tls1_1 ]]; then - num_bundles=1 - bundle_size=$nr_ossl_ciphers - fi - for (( bundle=0; bundle < num_bundles; bundle++ )); do - end_of_bundle=$(( (bundle+1)*bundle_size )) - [[ $end_of_bundle -gt $nr_ossl_ciphers ]] && end_of_bundle=$nr_ossl_ciphers - while true; do - ciphers_to_test="" - tls13_ciphers_to_test="" - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - if ! "${ciphers_found2[i]}"; then - if [[ "${ciph2[i]}" == TLS13* ]] || [[ "${ciph2[i]}" == TLS_* ]] || [[ "${ciph2[i]}" == AEAD-* ]]; then - tls13_ciphers_to_test+=":${ciph2[i]}" - else - ciphers_to_test+=":${ciph2[i]}" - fi - fi - done - [[ -z "$ciphers_to_test" ]] && [[ -z "$tls13_ciphers_to_test" ]] && break - $OPENSSL s_client $(s_client_options "$proto -cipher "\'${ciphers_to_test:1}\'" -ciphersuites "\'${tls13_ciphers_to_test:1}\'" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE = 128 ciphers. So, - # test cipher suites in bundles of 128 or less. - num_bundles=$nr_nonossl_ciphers/128 - [[ $((nr_nonossl_ciphers%128)) -ne 0 ]] && num_bundles+=1 - - bundle_size=$nr_nonossl_ciphers/$num_bundles - [[ $((nr_nonossl_ciphers%num_bundles)) -ne 0 ]] && bundle_size+=1 - fi - - for proto in 04 03 02 01 00; do - for (( bundle=0; bundle < num_bundles; bundle++ )); do - end_of_bundle=$(( (bundle+1)*bundle_size )) - [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers - while true; do - ciphers_to_test="" - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" - done - [[ -z "$ciphers_to_test" ]] && break - [[ "$proto" == 04 ]] && [[ ! "$ciphers_to_test" =~ ,\ 13,[0-9a-f][0-9a-f] ]] && break - ciphers_to_test="$(strip_inconsistent_ciphers "$proto" "$ciphers_to_test")" - [[ -z "$ciphers_to_test" ]] && break - if "$SHOW_SIGALGO"; then - tls_sockets "$proto" "${ciphers_to_test:2}, 00,ff" "all" - else - tls_sockets "$proto" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" - fi - sclient_success=$? - [[ $sclient_success -ne 0 ]] && [[ $sclient_success -ne 2 ]] && break - cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - [[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break - done - [[ $i -eq $end_of_bundle ]] && break - i=${index[i]} - ciphers_found[i]=true - [[ "${kx[i]}" == "Kx=any" ]] && kx[i]="$(read_dhtype_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then - dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet) - kx[i]="${kx[i]} $dhlen" - fi - "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \ - sigalg[i]="$(read_sigalg_from_file "$HOSTCERT")" - done - done - done - - for (( i=0; i < nr_ciphers; i++ )); do - "${ciphers_found[i]}" || "$SHOW_EACH_C" || continue - neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}" "${export2[i]}" "${ciphers_found[i]}" - available="" - if "$SHOW_EACH_C"; then - if "${ciphers_found[i]}"; then - available="available" - pr_cyan "available" - else - available="not a/v" - pr_deemphasize "not a/v" - fi - fi - outln "${sigalg[i]}" - fileout "cipher_${normalized_hexcode[i]}" "INFO" "$(neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}" "${export2[i]}") $available" - done - "$using_sockets" && HAS_DH_BITS="$has_dh_bits" - tmpfile_handle ${FUNCNAME[0]}.txt - done - outln - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 # this is a single test for a cipher -} - - - -# Test for all ciphers locally configured (w/o distinguishing whether they are good or bad) -# -run_allciphers() { - local -i nr_ciphers_tested=0 nr_ciphers=0 nr_ossl_ciphers=0 nr_nonossl_ciphers=0 sclient_success=0 - local n auth mac hexc sslv2_ciphers="" s - local -a normalized_hexcode hexcode ciph sslvers kx enc export2 sigalg ossl_supported - local -i i end_of_bundle bundle bundle_size num_bundles - local -a ciphers_found ciphers_found2 hexcode2 ciph2 rfc_ciph2 - local -i -a index - local proto protos_to_try - local dhlen available ciphers_to_test tls13_ciphers_to_test supported_sslv2_ciphers - local has_dh_bits="$HAS_DH_BITS" - local using_sockets=true - - "$SSL_NATIVE" && using_sockets=false - "$FAST" && using_sockets=false - [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false - - # get a list of all the cipher suites to test - if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - hexc="$(tolower "${TLS_CIPHER_HEXCODE[i]}")" - ciph[i]="${TLS_CIPHER_OSSL_NAME[i]}" - sslvers[i]="${TLS_CIPHER_SSLVERS[i]}" - kx[i]="${TLS_CIPHER_KX[i]}" - enc[i]="${TLS_CIPHER_ENC[i]}" - export2[i]="${TLS_CIPHER_EXPORT[i]}" - ciphers_found[i]=false - sigalg[i]="" - ossl_supported[i]=${TLS_CIPHER_OSSL_SUPPORTED[i]} - if "$using_sockets" && ! "$HAS_DH_BITS" && [[ ${kx[i]} == Kx=ECDH || ${kx[i]} == Kx=DH || ${kx[i]} == Kx=EDH ]]; then - ossl_supported[i]=false - fi - if [[ ${#hexc} -eq 9 ]]; then - hexcode[i]="${hexc:2:2},${hexc:7:2}" - if [[ "${hexc:2:2}" == 00 ]]; then - normalized_hexcode[i]="x${hexc:7:2}" - else - normalized_hexcode[i]="x${hexc:2:2}${hexc:7:2}" - fi - else - hexcode[i]="${hexc:2:2},${hexc:7:2},${hexc:12:2}" - normalized_hexcode[i]="x${hexc:2:2}${hexc:7:2}${hexc:12:2}" - sslv2_ciphers="$sslv2_ciphers, ${hexcode[i]}" - fi - if "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}"; then - nr_ciphers_tested+=1 - fi - done - nr_ciphers=$TLS_NR_CIPHERS - else - while read -r hexc n ciph[nr_ciphers] sslvers[nr_ciphers] kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do - ciphers_found[nr_ciphers]=false - if [[ ${#hexc} -eq 9 ]]; then - if [[ "${hexc:2:2}" == 00 ]]; then - normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:7:2}")" - else - normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:2:2}${hexc:7:2}")" - fi - else - normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:2:2}${hexc:7:2}${hexc:12:2}")" - fi - sigalg[nr_ciphers]="" - ossl_supported[nr_ciphers]=true - nr_ciphers=$nr_ciphers+1 - done < <(actually_supported_osslciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 'ALL' "-V") - nr_ciphers_tested=$nr_ciphers - fi - - if "$using_sockets"; then - sslv2_sockets "${sslv2_ciphers:2}" "true" - if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then - supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" - "$SHOW_SIGALGO" && s="$(read_sigalg_from_file "$HOSTCERT")" - for (( i=0 ; i$TMPFILE 2>$ERRFILE = 128 ciphers. So, - # test cipher suites in bundles of 128 or less. - num_bundles=$nr_ossl_ciphers/128 - [[ $((nr_ossl_ciphers%128)) -ne 0 ]] && num_bundles+=1 - - bundle_size=$nr_ossl_ciphers/$num_bundles - [[ $((nr_ossl_ciphers%num_bundles)) -ne 0 ]] && bundle_size+=1 - fi - - if "$HAS_TLS13"; then - protos_to_try="-no_ssl2 -tls1_2 -tls1_1 -tls1" - else - protos_to_try="-no_ssl2 -tls1_1 -tls1" - fi - "$HAS_SSL3" && protos_to_try+=" -ssl3" - - for proto in $protos_to_try; do - if [[ "$proto" == -tls1_1 ]]; then - num_bundles=1 - bundle_size=$nr_ossl_ciphers - fi - - [[ "$proto" != "-no_ssl2" ]] && [[ $(has_server_protocol "${proto:1}") -eq 1 ]] && continue - for (( bundle=0; bundle < num_bundles; bundle++ )); do - end_of_bundle=$(( (bundle+1)*bundle_size )) - [[ $end_of_bundle -gt $nr_ossl_ciphers ]] && end_of_bundle=$nr_ossl_ciphers - while true; do - ciphers_to_test="" - tls13_ciphers_to_test="" - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - if ! "${ciphers_found2[i]}"; then - if [[ "${ciph2[i]}" == TLS13* ]] || [[ "${ciph2[i]}" == TLS_* ]] || [[ "${ciph2[i]}" == AEAD-* ]]; then - tls13_ciphers_to_test+=":${ciph2[i]}" - else - ciphers_to_test+=":${ciph2[i]}" - fi - fi - done - [[ -z "$ciphers_to_test" ]] && [[ -z "$tls13_ciphers_to_test" ]] && break - $OPENSSL s_client $(s_client_options "$proto -cipher "\'${ciphers_to_test:1}\'" -ciphersuites "\'${tls13_ciphers_to_test:1}\'" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE = 128 ciphers. So, - # test cipher suites in bundles of 128 or less. - num_bundles=$nr_nonossl_ciphers/128 - [[ $((nr_nonossl_ciphers%128)) -ne 0 ]] && num_bundles+=1 - - bundle_size=$nr_nonossl_ciphers/$num_bundles - [[ $((nr_nonossl_ciphers%num_bundles)) -ne 0 ]] && bundle_size+=1 - fi - - for proto in 04 03 02 01 00; do - for (( bundle=0; bundle < num_bundles; bundle++ )); do - end_of_bundle=$(( (bundle+1)*bundle_size )) - [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers - while true; do - ciphers_to_test="" - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" - done - [[ -z "$ciphers_to_test" ]] && break - [[ "$proto" == 04 ]] && [[ ! "$ciphers_to_test" =~ ,\ 13,[0-9a-f][0-9a-f] ]] && break - ciphers_to_test="$(strip_inconsistent_ciphers "$proto" "$ciphers_to_test")" - [[ -z "$ciphers_to_test" ]] && break - if "$SHOW_SIGALGO"; then - tls_sockets "$proto" "${ciphers_to_test:2}, 00,ff" "all" - else - tls_sockets "$proto" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" - fi - sclient_success=$? - [[ $sclient_success -ne 0 ]] && [[ $sclient_success -ne 2 ]] && break - cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - [[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break - done - [[ $i -eq $end_of_bundle ]] && break - i=${index[i]} - ciphers_found[i]=true - [[ "${kx[i]}" == "Kx=any" ]] && kx[i]="$(read_dhtype_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then - dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet) - kx[i]="${kx[i]} $dhlen" - fi - "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && sigalg[i]="$(read_sigalg_from_file "$HOSTCERT")" - done - done - done - - for (( i=0 ; i$TMPFILE 2>$ERRFILE = 128 ciphers. So, - # test cipher suites in bundles of 128 or less. - num_bundles=$nr_ossl_ciphers/128 - [[ $((nr_ossl_ciphers%128)) -ne 0 ]] && num_bundles+=1 - - bundle_size=$nr_ossl_ciphers/$num_bundles - [[ $((nr_ossl_ciphers%num_bundles)) -ne 0 ]] && bundle_size+=1 - fi - - for (( bundle=0; bundle < num_bundles; bundle++ )); do - end_of_bundle=$(( (bundle+1)*bundle_size )) - [[ $end_of_bundle -gt $nr_ossl_ciphers ]] && end_of_bundle=$nr_ossl_ciphers - for (( success=0; success==0 ; 1 )); do - ciphers_to_test="" - tls13_ciphers_to_test="" - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - if ! "${ciphers_found2[i]}"; then - if [[ "$proto" == -tls1_3 ]]; then - tls13_ciphers_to_test+=":${ciph2[i]}" - else - ciphers_to_test+=":${ciph2[i]}" - fi - fi - done - success=1 - if [[ -n "$ciphers_to_test" ]] || [[ -n "$tls13_ciphers_to_test" ]]; then - $OPENSSL s_client $(s_client_options "-cipher "\'${ciphers_to_test:1}\'" -ciphersuites "\'${tls13_ciphers_to_test:1}\'" $proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE = 128 ciphers. So, - # test cipher suites in bundles of 128 or less. - num_bundles=$nr_nonossl_ciphers/128 - [[ $((nr_nonossl_ciphers%128)) -ne 0 ]] && num_bundles+=1 - - bundle_size=$nr_nonossl_ciphers/$num_bundles - [[ $((nr_nonossl_ciphers%num_bundles)) -ne 0 ]] && bundle_size+=1 - fi - - for (( bundle=0; bundle < num_bundles; bundle++ )); do - end_of_bundle=$(( (bundle+1)*bundle_size )) - [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers - for (( success=0; success==0 ; 1 )); do - ciphers_to_test="" - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" - done - success=1 - if [[ -n "$ciphers_to_test" ]]; then - if "$wide" && "$SHOW_SIGALGO"; then - tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "all" - else - tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" - fi - if [[ $? -eq 0 ]]; then - success=0 - cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - [[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break - done - i=${index[i]} - ciphers_found[i]=true - proto_supported=true - "$wide" && [[ "$proto" == -tls1_3 ]] && kx[i]="$(read_dhtype_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - if "$wide" && [[ ${kx[i]} == Kx=ECDH || ${kx[i]} == Kx=DH || ${kx[i]} == Kx=EDH ]]; then - dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet) - kx[i]="${kx[i]} $dhlen" - fi - "$wide" && "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \ - sigalg[i]="$(read_sigalg_from_file "$HOSTCERT")" - fi - fi - done - done - fi - - if "$wide" && [[ "${FUNCNAME[1]}" == run_server_preference ]] && "$proto_supported"; then - if ! "$serverpref_known"; then - outln " (listed by strength)" - else - # Determine the best and worst quality level findings for the supported ciphers - for (( i=0 ; i> "$SOCK_REPLY_FILE" - rm "$sock_reply_file3" - fi - - check_tls_serverhellodone "$tls_hello_ascii" "ephemeralkey" - hello_done=$? - fi - done - - debugme echo "reading server hello..." - if [[ "$DEBUG" -ge 4 ]]; then - hexdump -C $SOCK_REPLY_FILE | head -6 - echo - fi - if [[ "${tls_hello_ascii:0:1}" == 8 ]]; then - parse_sslv2_serverhello "$SOCK_REPLY_FILE" "false" - if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then - echo "Protocol : SSLv2" > "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" - DETECTED_TLS_VERSION="0200" - ret=0 - else - ret=1 - fi - else - parse_tls_serverhello "$tls_hello_ascii" "ephemeralkey" "$cipher_list_2send" - save=$? - - if [[ $save -eq 0 ]]; then - send_close_notify "$DETECTED_TLS_VERSION" - fi - - if [[ $DEBUG -ge 2 ]]; then - # see https://secure.wand.net.nz/trac/libprotoident/wiki/SSL - lines=$(count_lines "$(hexdump -C "$SOCK_REPLY_FILE" 2>$ERRFILE)") - tm_out " ($lines lines returned) " - fi - - # determine the return value for higher level, so that they can tell what the result is - if [[ $save -eq 1 ]] || [[ $lines -eq 1 ]]; then - ret=1 # NOT available - else - ret=0 - fi - debugme tmln_out - fi - - close_socket 5 - TMPFILE=$SOCK_REPLY_FILE - tmpfile_handle ${FUNCNAME[0]}.dd - return $ret -} - -run_client_simulation() { - # Runs browser simulations. Browser capabilities gathered from: - # https://www.ssllabs.com/ssltest/clients.html on 10 jan 2016 - local names=() - local short=() - local protos=() - local ch_ciphers=() - local ciphersuites=() - local tlsvers=() - local ch_sni=() - local warning=() - local handshakebytes=() - local lowest_protocol=() - local highest_protocol=() - local service=() - local minDhBits=() - local maxDhBits=() - local minRsaBits=() - local maxRsaBits=() - local minEcdsaBits=() - local curves=() - local requiresSha2=() - local current=() - local i=0 - local name tls proto cipher temp what_dh bits curve supported_curves - local has_dh_bits using_sockets=true - local client_service - local options - local -i ret=0 - local jsonID="clientsimulation" - local client_service="" - - # source the external file - . "$TESTSSL_INSTALL_DIR/etc/client-simulation.txt" 2>/dev/null - if [[ $? -ne 0 ]]; then - prln_local_problem "couldn't find client simulation data in $TESTSSL_INSTALL_DIR/etc/client-simulation.txt" - return 1 - fi - - "$SSL_NATIVE" && using_sockets=false - - if [[ $SERVICE != "" ]]; then - client_service="$SERVICE" - elif [[ -n "$STARTTLS_PROTOCOL" ]]; then - # Can we take the service from STARTTLS? - client_service=$(toupper "${STARTTLS_PROTOCOL%s}") # strip trailing 's' in ftp(s), smtp(s), pop3(s), etc - elif "$ASSUME_HTTP"; then - client_service="HTTP" - else - outln "Could not determine the protocol, only simulating generic clients." - fi - - outln - pr_headline " Running client simulations " - [[ "$client_service" == HTTP ]] && pr_headline "($client_service) " - if "$using_sockets"; then - pr_headlineln "via sockets " - else - pr_headline "via openssl " - prln_warning " -- pls note \"--ssl-native\" will return some false results" - fileout "$jsonID" "WARN" "You shouldn't run this with \"--ssl-native\" as you will get false results" - ret=1 - fi - outln - debugme echo - - if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]]; then - out " Browser Protocol Cipher Suite Name (OpenSSL) " - { "$using_sockets" || "$HAS_DH_BITS"; } && out "Forward Secrecy" - outln - out "--------------------------------------------------------------------------" - else - out " Browser Protocol Cipher Suite Name (IANA/RFC) " - { "$using_sockets" || "$HAS_DH_BITS"; } && out "Forward Secrecy" - outln - out "------------------------------------------------------------------------------------------" - fi - { "$using_sockets" || "$HAS_DH_BITS"; } && out "----------------------" - outln - if ! "$using_sockets"; then - # We can't use the connectivity checker here as of now the openssl reply is always empty (reason??) - save_max_ossl_fail=$MAX_OSSL_FAIL - nr_ossl_fail=$NR_OSSL_FAIL - MAX_OSSL_FAIL=100 - fi - for name in "${short[@]}"; do - if "${current[i]}" || "$ALL_CLIENTS" ; then - # for ANY we test this service or if the service we determined from STARTTLS matches - if [[ "${service[i]}" == ANY ]] || [[ "${service[i]}" =~ $client_service ]]; then - out " $(printf -- "%-29s" "${names[i]}")" - if "$using_sockets" && [[ -n "${handshakebytes[i]}" ]]; then - client_simulation_sockets "${handshakebytes[i]}" - sclient_success=$? - if [[ $sclient_success -eq 0 ]]; then - if [[ "0x${DETECTED_TLS_VERSION}" -lt ${lowest_protocol[i]} ]] || \ - [[ "0x${DETECTED_TLS_VERSION}" -gt ${highest_protocol[i]} ]]; then - sclient_success=1 - fi - [[ $sclient_success -eq 0 ]] && cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE >$ERRFILE - fi - else - if [[ -n "${curves[i]}" ]]; then - # "$OPENSSL s_client" will fail if the -curves option includes any unsupported curves. - supported_curves="" - for curve in $(colon_to_spaces "${curves[i]}"); do - # Attention! secp256r1 = prime256v1 and secp192r1 = prime192v1 - # We need to map two curves here as otherwise handshakes will go wrong if "-curves" are supplied - # https://github.com/openssl/openssl/blob/master/apps/ecparam.c#L221 + ./ssl/t1_lib.c - [[ "$curve" =~ secp256r1 ]] && curve="${curve//secp256r1/prime256v1}" - [[ "$curve" =~ secp192r1 ]] && curve="${curve//secp192r1/prime192v1}" - [[ "$OSSL_SUPPORTED_CURVES" =~ \ $curve\ ]] && supported_curves+=":$curve" - done - curves[i]="" - [[ -n "$supported_curves" ]] && curves[i]="-curves ${supported_curves:1}" - fi - options="$(s_client_options "-cipher ${ch_ciphers[i]} -ciphersuites "\'${ciphersuites[i]}\'" ${curves[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${ch_sni[i]}")" - debugme echo "$OPENSSL s_client $options $TMPFILE 2>$ERRFILE - sclient_connect_successful $? $TMPFILE - sclient_success=$? - fi - if [[ $sclient_success -eq 0 ]]; then - # If an ephemeral DH key was used, check that the number of bits is within range. - temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TMPFILE") # extract line - what_dh="${temp%%,*}" - bits="${temp##*, }" - # formatting - curve="${temp#*, }" - if [[ "$curve" == $bits ]]; then - curve="" - else - curve="${curve%%,*}" - fi - bits="${bits/bits/}" - bits="${bits// /}" - if [[ "$what_dh" == X25519 ]] || [[ "$what_dh" == X448 ]]; then - curve="$what_dh" - what_dh="ECDH" - fi - if [[ "$what_dh" == DH ]]; then - [[ ${minDhBits[i]} -ne -1 ]] && [[ $bits -lt ${minDhBits[i]} ]] && sclient_success=1 - [[ ${maxDhBits[i]} -ne -1 ]] && [[ $bits -gt ${maxDhBits[i]} ]] && sclient_success=1 - fi - fi - if [[ $sclient_success -ne 0 ]]; then - outln "No connection" - fileout "${jsonID}-${short[i]}" "INFO" "No connection" - else - proto=$(get_protocol $TMPFILE) - # hack: - [[ "$proto" == TLSv1 ]] && proto="TLSv1.0" - [[ "$proto" == SSLv3 ]] && proto="SSLv3 " - if [[ "$proto" == TLSv1.2 ]] && { ! "$using_sockets" || [[ -z "${handshakebytes[i]}" ]]; }; then - # OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0. Need to figure out which one it is... - for tls in ${tlsvers[i]}; do - # If the handshake data includes TLS 1.3 we need to remove it, otherwise the - # simulation will fail with # 'Oops: openssl s_client connect problem' - # before/after trying another protocol. We only print a warning it in debug mode - # as otherwise we would need e.g. handle the curves in a similar fashion -- not - # to speak about ciphers - if [[ $tls =~ 1_3 ]] && ! "$HAS_TLS13"; then - debugme pr_local_problem "TLS 1.3 not supported, " - continue - fi - options="$(s_client_options "$tls -cipher ${ch_ciphers[i]} -ciphersuites "\'${ciphersuites[i]}\'" ${curves[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${ch_sni[i]}")" - debugme echo "$OPENSSL s_client $options $TMPFILE 2>$ERRFILE - sclient_connect_successful $? $TMPFILE - sclient_success=$? - if [[ $sclient_success -eq 0 ]]; then - case "$tls" in - "-tls1_2") break ;; - "-tls1_1") proto="TLSv1.1" - break ;; - "-tls1") proto="TLSv1.0" - break ;; - esac - fi - done - fi - cipher=$(get_cipher $TMPFILE) - if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]] && [[ "$cipher" == TLS_* || "$cipher" == SSL_* ]]; then - cipher="$(rfc2openssl "$cipher")" - [[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE) - elif [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]] && [[ "$cipher" != TLS_* ]] && [[ "$cipher" != SSL_* ]]; then - cipher="$(openssl2rfc "$cipher")" - [[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE) - fi - out "$proto " - if [[ "$COLOR" -le 2 ]]; then - out "$cipher" - else - pr_cipher_quality "$cipher" - fi - if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]]; then - print_n_spaces "$((34-${#cipher}))" - else - print_n_spaces "$((50-${#cipher}))" - fi - if [[ -n "$what_dh" ]]; then - [[ -n "$curve" ]] && curve="($curve)" - if [[ "$what_dh" == ECDH ]]; then - pr_ecdh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve" - else - pr_dh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve" - fi - else - if "$HAS_DH_BITS" || { "$using_sockets" && [[ -n "${handshakebytes[i]}" ]]; }; then - out "No FS" - fi - fi - outln - if [[ -n "${warning[i]}" ]]; then - out " " - outln "${warning[i]}" - fi - fileout "${jsonID}-${short[i]}" "INFO" "$proto $cipher ${warning[i]}" - debugme cat $TMPFILE - fi - fi # correct service? - fi #current? - ((i++)) - done - if ! "$using_sockets"; then - # restore from above - MAX_OSSL_FAIL=$save_max_ossl_fail - NR_OSSL_FAIL=$nr_ossl_fail - fi - - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - -# generic function whether $1 is supported by s_client. -# Currently only used for protocols that's why we saved -connect $NXCONNECT. -sclient_supported() { - case "$1" in - -ssl2) - "$HAS_SSL2" || return 7 - ;; - -ssl3) - "$HAS_SSL3" || return 7 - ;; - -tls1_3) - "$HAS_TLS13" || return 7 - ;; - *) if $OPENSSL s_client "$1" &1 | grep -aiq "unknown option"; then - return 7 - fi - ;; - esac - return 0 -} - -# generic function whether $1 is supported by s_client ($2: string to display) -#TODO: we need to consider to remove the two instances from where this is called. -# -locally_supported() { - local -i ret - - [[ -n "$2" ]] && out "$2 " - sclient_supported "$1" - ret=$? - [[ $ret -eq 7 ]] && prln_local_problem "$OPENSSL doesn't support \"s_client $1\"" - return $ret -} - - -# The protocol check in run_protocols needs to be redone. The using_sockets part there kind of sucks. -# 1) we need to have a variable where the results are being stored so that every other test doesn't have to do this again -# --> we have that but certain information like "downgraded" are not being passed. That's not ok for run_protocols()/ -# for all other functions we can use it -# 2) the code is old and one can do that way better -# We should do what's available and faster (openssl vs. sockets). Keep in mind that the socket reply for SSLv2 returns the number # of ciphers! -# -# arg1: -ssl2|-ssl3|-tls1|-tls1_1|-tls1_2|-tls1_3 -# -run_prototest_openssl() { - local -i ret=0 - local protos proto - - sclient_supported "$1" || return 7 - case "$1" in - -ssl2) protos="-ssl2" ;; - -ssl3) protos="-ssl3" ;; - -tls1) protos="-no_tls1_2 -no_tls1_1 -no_ssl2"; "$HAS_TLS13" && protos+=" -no_tls1_3" ;; - -tls1_1) protos="-no_tls1_2 -no_ssl2"; "$HAS_TLS13" && protos+=" -no_tls1_3" ;; - -tls1_2) protos="-no_ssl2"; "$HAS_TLS13" && protos+=" -no_tls1_3" ;; - -tls1_3) protos="" ;; - esac - - #FIXME: we have here HAS_SSL(2|3) and more but we don't use that - $OPENSSL s_client $(s_client_options "-state $protos $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>&1 $TMPFILE 2>&1 =2)" - ;; - 1) # no sslv2 server hello returned, like in openlitespeed which returns HTTP! - prln_svrty_best "not offered (OK)" - fileout "$jsonID" "OK" "not offered" - add_proto_offered ssl2 no - ;; - 0) # reset - prln_svrty_best "not offered (OK)" - fileout "$jsonID" "OK" "not offered" - add_proto_offered ssl2 no - ;; - 4) out "likely "; pr_svrty_best "not offered (OK), " - fileout "$jsonID" "OK" "likely not offered" - add_proto_offered ssl2 no - pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" - fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" - ;; - 3) lines=$(count_lines "$(hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" 2>/dev/null)") - [[ "$DEBUG" -ge 2 ]] && tm_out " ($lines lines) " - if [[ "$lines" -gt 1 ]]; then - nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) - add_proto_offered ssl2 yes - set_grade_cap "F" "SSLv2 is offered" - if [[ 0 -eq "$nr_ciphers_detected" ]]; then - prln_svrty_high "supported but couldn't detect a cipher and vulnerable to CVE-2015-3197 "; - fileout "$jsonID" "HIGH" "offered, no cipher" "CVE-2015-3197" "CWE-310" - else - pr_svrty_critical "offered (NOT ok), also VULNERABLE to DROWN attack"; - outln " -- $nr_ciphers_detected ciphers" - fileout "$jsonID" "CRITICAL" "vulnerable with $nr_ciphers_detected ciphers" - fi - fi - ;; - *) pr_fixme "unexpected value around line $((LINENO))"; outln "$debug_recomm" - ((ret++)) - ;; - esac - debugme tmln_out - else - run_prototest_openssl "-ssl2" - case $? in - 0) prln_svrty_critical "offered (NOT ok)" - fileout "$jsonID" "CRITICAL" "offered" - add_proto_offered ssl2 yes - set_grade_cap "F" "SSLv2 is offered" - ;; - 1) prln_svrty_best "not offered (OK)" - fileout "$jsonID" "OK" "not offered" - add_proto_offered ssl2 no - ;; - 5) prln_svrty_high "CVE-2015-3197: $supported_no_ciph2"; - fileout "$jsonID" "HIGH" "offered, no cipher" "CVE-2015-3197" "CWE-310" - add_proto_offered ssl2 yes - set_grade_cap "F" "SSLv2 is offered" - ;; - 7) prln_local_problem "$OPENSSL doesn't support \"s_client -ssl2\"" - fileout "$jsonID" "WARN" "not tested due to lack of local support" - ((ret++)) - ;; - esac - fi - - pr_bold " SSLv3 "; - jsonID="SSLv3" - if [[ $(has_server_protocol ssl3) -eq 0 ]]; then - ret_val_ssl3=0 - elif "$using_sockets"; then - tls_sockets "00" "$TLS_CIPHER" - ret_val_ssl3=$? - else - run_prototest_openssl "-ssl3" - ret_val_ssl3=$? - fi - case $ret_val_ssl3 in - 0) prln_svrty_high "offered (NOT ok)" - fileout "$jsonID" "HIGH" "offered" - if "$using_sockets" || "$HAS_SSL3"; then - latest_supported="0300" - latest_supported_string="SSLv3" - fi - add_proto_offered ssl3 yes - set_grade_cap "B" "SSLv3 is offered" - ;; - 1) prln_svrty_best "not offered (OK)" - fileout "$jsonID" "OK" "not offered" - add_proto_offered ssl3 no - ;; - 2) if [[ "$DETECTED_TLS_VERSION" == 03* ]]; then - detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" - prln_svrty_critical "server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" - fileout "$jsonID" "CRITICAL" "server responded with higher version number ($detected_version_string) than requested by client" - else - if [[ ${#DETECTED_TLS_VERSION} -eq 4 ]]; then - prln_svrty_critical "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" - fileout "$jsonID" "CRITICAL" "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - else - prln_svrty_medium "strange, server ${DETECTED_TLS_VERSION}" - fileout "$jsonID" "MEDIUM" "strange, server ${DETECTED_TLS_VERSION}" - ((ret++)) - fi - fi - ;; - 3) pr_svrty_best "not offered (OK), " - fileout "$jsonID" "OK" "not offered" - add_proto_offered ssl3 no - pr_warning "SSL downgraded to STARTTLS plaintext"; outln - fileout "$jsonID" "WARN" "SSL downgraded to STARTTLS plaintext" - ;; - 4) out "likely "; pr_svrty_best "not offered (OK), " - fileout "$jsonID" "OK" "not offered" - add_proto_offered ssl3 no - pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" - fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" - ;; - 5) pr_svrty_high "$supported_no_ciph1" # protocol detected but no cipher --> comes from run_prototest_openssl - fileout "$jsonID" "HIGH" "$supported_no_ciph1" - add_proto_offered ssl3 yes - set_grade_cap "B" "SSLv3 is offered" - ;; - 7) if "$using_sockets" ; then - # can only happen in debug mode - pr_warning "strange reply, maybe a client side problem with SSLv3"; outln "$debug_recomm" - else - prln_local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" - fileout "$jsonID" "WARN" "not tested due to lack of local support" - fi - ;; - *) pr_fixme "unexpected value around line $((LINENO))"; outln "$debug_recomm" - ((ret++)) - ;; - esac - - pr_bold " TLS 1 "; - jsonID="TLS1" - if [[ $(has_server_protocol tls1) -eq 0 ]]; then - ret_val_tls1=0 - elif "$using_sockets"; then - tls_sockets "01" "$TLS_CIPHER" - ret_val_tls1=$? - else - run_prototest_openssl "-tls1" - ret_val_tls1=$? - fi - case $ret_val_tls1 in - 0) pr_svrty_low "offered" ; outln " (deprecated)" - fileout "$jsonID" "LOW" "offered (deprecated)" - latest_supported="0301" - latest_supported_string="TLSv1.0" - add_proto_offered tls1 yes - set_grade_cap "B" "TLS 1.0 offered" - ;; # nothing wrong with it -- per se - 1) out "not offered" - add_proto_offered tls1 no - if [[ -z $latest_supported ]]; then - outln - fileout "$jsonID" "INFO" "not offered" # neither good or bad - else - prln_svrty_critical " -- connection failed rather than downgrading to $latest_supported_string (NOT ok)" - fileout "$jsonID" "CRITICAL" "connection failed rather than downgrading to $latest_supported_string" - fi - ;; - 2) pr_svrty_medium "not offered" - add_proto_offered tls1 no - if [[ "$DETECTED_TLS_VERSION" == 0300 ]]; then - [[ $DEBUG -ge 1 ]] && tm_out " -- downgraded" - outln - fileout "$jsonID" "MEDIUM" "not offered, and downgraded to SSL" - elif [[ "$DETECTED_TLS_VERSION" == 03* ]]; then - detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" - prln_svrty_critical " -- server responded with higher version number ($detected_version_string) than requested by client" - fileout "$jsonID" "CRITICAL" "server responded with higher version number ($detected_version_string) than requested by client" - else - if [[ ${#DETECTED_TLS_VERSION} -eq 4 ]]; then - prln_svrty_critical "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" - fileout "$jsonID" "CRITICAL" "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - else - prln_svrty_medium " -- strange, server ${DETECTED_TLS_VERSION}" - fileout "$jsonID" "MEDIUM" "strange, server ${DETECTED_TLS_VERSION}" - fi - fi - ;; - 3) out "not offered, " - fileout "$jsonID" "OK" "not offered" - add_proto_offered tls1 no - pr_warning "TLS downgraded to STARTTLS plaintext"; outln - fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext" - ;; - 4) out "likely not offered, " - fileout "$jsonID" "INFO" "likely not offered" - add_proto_offered tls1 no - pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" - fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" - ;; - 5) outln "$supported_no_ciph1" # protocol detected but no cipher --> comes from run_prototest_openssl - fileout "$jsonID" "INFO" "$supported_no_ciph1" - add_proto_offered tls1 yes - set_grade_cap "B" "TLS 1.0 offered" - ;; - 7) if "$using_sockets" ; then - # can only happen in debug mode - pr_warning "strange reply, maybe a client side problem with TLS 1.0"; outln "$debug_recomm" - else - prln_local_problem "$OPENSSL doesn't support \"s_client -tls1\"" - fileout "$jsonID" "WARN" "not tested due to lack of local support" - fi - ((ret++)) - ;; - *) pr_fixme "unexpected value around line $((LINENO))"; outln "$debug_recomm" - ((ret++)) - ;; - esac - - pr_bold " TLS 1.1 "; - jsonID="TLS1_1" - if [[ $(has_server_protocol tls1_1) -eq 0 ]]; then - ret_val_tls11=0 - elif "$using_sockets"; then - tls_sockets "02" "$TLS_CIPHER" - ret_val_tls11=$? - else - run_prototest_openssl "-tls1_1" - ret_val_tls11=$? - fi - case $ret_val_tls11 in - 0) pr_svrty_low "offered" ; outln " (deprecated)" - fileout "$jsonID" "LOW" "offered (deprecated)" - latest_supported="0302" - latest_supported_string="TLSv1.1" - add_proto_offered tls1_1 yes - set_grade_cap "B" "TLS 1.1 offered" - ;; # nothing wrong with it - 1) out "not offered" - add_proto_offered tls1_1 no - if [[ -z $latest_supported ]]; then - outln - fileout "$jsonID" "INFO" "not offered" # neither good or bad - else - prln_svrty_critical " -- connection failed rather than downgrading to $latest_supported_string" - fileout "$jsonID" "CRITICAL" "connection failed rather than downgrading to $latest_supported_string" - fi - ;; - 2) out "not offered" - add_proto_offered tls1_1 no - if [[ "$DETECTED_TLS_VERSION" == "$latest_supported" ]]; then - [[ $DEBUG -ge 1 ]] && tm_out " -- downgraded" - outln - fileout "$jsonID" "CRITICAL" "TLSv1.1 is not offered, and downgraded to a weaker protocol" - elif [[ "$DETECTED_TLS_VERSION" == 0300 ]] && [[ "$latest_supported" == 0301 ]]; then - prln_svrty_critical " -- server supports TLSv1.0, but downgraded to SSLv3 (NOT ok)" - fileout "$jsonID" "CRITICAL" "not offered, and downgraded to SSLv3 rather than TLSv1.0" - elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -gt 0x0302 ]]; then - detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" - prln_svrty_critical " -- server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" - fileout "$jsonID" "CRITICAL" "not offered, server responded with higher version number ($detected_version_string) than requested by client" - else - if [[ ${#DETECTED_TLS_VERSION} -eq 4 ]]; then - prln_svrty_critical "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" - fileout "$jsonID" "CRITICAL" "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - else - prln_svrty_medium " -- strange, server ${DETECTED_TLS_VERSION}" - fileout "$jsonID" "MEDIUM" "strange, server ${DETECTED_TLS_VERSION}" - fi - fi - ;; - 3) out "not offered, " - fileout "$jsonID" "OK" "not offered" - add_proto_offered tls1_1 no - pr_warning "TLS downgraded to STARTTLS plaintext"; outln - fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext" - ;; - 4) out "likely not offered, " - fileout "$jsonID" "INFO" "not offered" - add_proto_offered tls1_1 no - pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" - fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" - ;; - 5) outln "$supported_no_ciph1" # protocol detected but no cipher --> comes from run_prototest_openssl - fileout "$jsonID" "INFO" "$supported_no_ciph1" - add_proto_offered tls1_1 yes - set_grade_cap "B" "TLS 1.1 offered" - ;; - 7) if "$using_sockets" ; then - # can only happen in debug mode - pr_warning "strange reply, maybe a client side problem with TLS 1.1"; outln "$debug_recomm" - else - prln_local_problem "$OPENSSL doesn't support \"s_client -tls1_1\"" - fileout "$jsonID" "WARN" "not tested due to lack of local support" - fi - ((ret++)) - ;; - *) pr_fixme "unexpected value around line $((LINENO))"; outln "$debug_recomm" - ((ret++)) - ;; - esac - - # Now, we are doing a basic/pre test for TLS 1.2 and 1.3 in order not to penalize servers (medium) - # running TLS 1.3 only when TLS 1.2 is not offered. 0 and 5 are the return codes for - # TLS 1.3 support (kind of, including deprecated pre-versions of TLS 1.3) - if [[ $(has_server_protocol tls1_2) -eq 0 ]]; then - ret_val_tls12=0 - elif "$using_sockets"; then - tls_sockets "03" "$TLS12_CIPHER" - ret_val_tls12=$? - tls12_detected_version="$DETECTED_TLS_VERSION" - else - run_prototest_openssl "-tls1_2" - ret_val_tls12=$? - tls12_detected_version="$DETECTED_TLS_VERSION" - fi - - if [[ $(has_server_protocol tls1_3) -eq 0 ]]; then - ret_val_tls13=0 - elif "$using_sockets"; then - # Need to ensure that at most 128 ciphers are included in ClientHello. - # If the TLSv1.2 test in determine_optimal_sockets_params() was successful, - # then use the 5 TLSv1.3 ciphers plus the cipher selected in the TLSv1.2 test. - # If the TLSv1.2 test was not successful, then just use the 5 TLSv1.3 ciphers - # plus the list of ciphers used in all of the previous tests ($TLS_CIPHER). - if [[ -n "$TLS12_CIPHER_OFFERED" ]]; then - tls13_ciphers_to_test="$TLS13_CIPHER, $TLS12_CIPHER_OFFERED, 00,ff" - else - tls13_ciphers_to_test="$TLS13_CIPHER,$TLS_CIPHER" - fi - tls_sockets "04" "$tls13_ciphers_to_test" - ret_val_tls13=$? - else - run_prototest_openssl "-tls1_3" - ret_val_tls13=$? - fi - if [[ $ret_val_tls13 -eq 0 ]] || [[ $ret_val_tls13 -eq 5 ]]; then - offers_tls13=true # This variable comes in handy for further if statements below - fi - # Done with pretesting TLS 1.2 and 1.3. - - pr_bold " TLS 1.2 "; - jsonID="TLS1_2" - case $ret_val_tls12 in - 0) prln_svrty_best "offered (OK)" - fileout "$jsonID" "OK" "offered" - latest_supported="0303" - latest_supported_string="TLSv1.2" - add_proto_offered tls1_2 yes - ;; # GCM cipher in TLS 1.2: very good! - 1) add_proto_offered tls1_2 no - if "$offers_tls13"; then - out "not offered" - else - pr_svrty_medium "not offered" - fi - if [[ -z $latest_supported ]]; then - outln - if "$offers_tls13"; then - fileout "$jsonID" "INFO" "not offered" - else - fileout "$jsonID" "MEDIUM" "not offered" # TLS 1.3, no TLS 1.2 --> no GCM, penalty - set_grade_cap "C" "TLS 1.2 or TLS 1.3 are not offered" - fi - else - prln_svrty_critical " -- connection failed rather than downgrading to $latest_supported_string" - fileout "$jsonID" "CRITICAL" "connection failed rather than downgrading to $latest_supported_string" - fi - ;; - 2) add_proto_offered tls1_2 no - set_grade_cap "C" "TLS 1.2 is not offered" - pr_svrty_medium "not offered and downgraded to a weaker protocol" - if [[ "$tls12_detected_version" == 0300 ]]; then - detected_version_string="SSLv3" - elif [[ "$tls12_detected_version" == 03* ]]; then - detected_version_string="TLSv1.$((0x$tls12_detected_version-0x0301))" - fi - if [[ "$tls12_detected_version" == "$latest_supported" ]]; then - outln - fileout "$jsonID" "MEDIUM" "not offered and downgraded to a weaker protocol" - elif [[ "$tls12_detected_version" == 03* ]] && [[ 0x$tls12_detected_version -lt 0x$latest_supported ]]; then - prln_svrty_critical " -- server supports $latest_supported_string, but downgraded to $detected_version_string" - fileout "$jsonID" "CRITICAL" "not offered, and downgraded to $detected_version_string rather than $latest_supported_string" - elif [[ "$tls12_detected_version" == 03* ]] && [[ 0x$tls12_detected_version -gt 0x0303 ]]; then - prln_svrty_critical " -- server responded with higher version number ($detected_version_string) than requested by client" - fileout "$jsonID" "CRITICAL" "not offered, server responded with higher version number ($detected_version_string) than requested by client" - else - if [[ ${#tls12_detected_version} -eq 4 ]]; then - prln_svrty_critical "server responded with version number ${tls12_detected_version:0:2}.${tls12_detected_version:2:2} (NOT ok)" - fileout "$jsonID" "CRITICAL" "server responded with version number ${tls12_detected_version:0:2}.${tls12_detected_version:2:2}" - else - prln_svrty_medium " -- strange, server ${tls12_detected_version}" - fileout "$jsonID" "MEDIUM" "strange, server ${tls12_detected_version}" - fi - fi - ;; - 3) out "not offered, " - fileout "$jsonID" "INFO" "not offered" - add_proto_offered tls1_2 no - set_grade_cap "C" "TLS 1.2 is not offered" - pr_warning "TLS downgraded to STARTTLS plaintext"; outln - fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext" - ;; - 4) out "likely "; pr_svrty_medium "not offered, " - fileout "$jsonID" "MEDIUM" "not offered" - add_proto_offered tls1_2 no - set_grade_cap "C" "TLS 1.2 is not offered" - pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" - fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" - ;; - 5) outln "$supported_no_ciph1" # protocol detected, but no cipher --> comes from run_prototest_openssl - fileout "$jsonID" "INFO" "$supported_no_ciph1" - add_proto_offered tls1_2 yes - ;; - 7) if "$using_sockets" ; then - # can only happen in debug mode - pr_warning "strange reply, maybe a client side problem with TLS 1.2"; outln "$debug_recomm" - else - prln_local_problem "$OPENSSL doesn't support \"s_client -tls1_2\"" - fileout "$jsonID" "WARN" "not tested due to lack of local support" - fi - ((ret++)) - ;; - *) pr_fixme "unexpected value around line $((LINENO))"; outln "$debug_recomm" - ((ret++)) - ;; - esac - - pr_bold " TLS 1.3 "; - jsonID="TLS1_3" - case $ret_val_tls13 in - 0) if ! "$using_sockets"; then - prln_svrty_best "offered (OK)" - fileout "$jsonID" "OK" "offered" - else - # If TLS 1.3 is offered, then its support was detected - # by determine_optimal_sockets_params(). - if [[ $(has_server_protocol tls1_3_rfc8446) -eq 0 ]]; then - drafts_offered+=" 0304 " - else - for i in 1C 1B 1A 19 18 17 16 15 14 13 12; do - if [[ $(has_server_protocol tls1_3_draft$(hex2dec "$i")) -eq 0 ]]; then - drafts_offered+=" 7F$i " - break - fi - done - fi - KEY_SHARE_EXTN_NR="28" - while true; do - supported_versions="" - for i in 16 15 14 13 12; do - [[ "$drafts_offered" =~ \ 7F$i\ ]] || supported_versions+=",7f,$i" - done - [[ -z "$supported_versions" ]] && break - supported_versions="00, 2b, 00, $(printf "%02x" $((${#supported_versions}/3+1))), $(printf "%02x" $((${#supported_versions}/3))) $supported_versions" - tls_sockets "04" "$TLS13_CIPHER" "" "$supported_versions" - [[ $? -eq 0 ]] || break - if [[ "${TLS_SERVER_HELLO:8:3}" == 7F1 ]]; then - drafts_offered+=" ${TLS_SERVER_HELLO:8:4} " - elif [[ "$TLS_SERVER_HELLO" =~ 002B00027F1[2-6] ]]; then - drafts_offered+=" ${BASH_REMATCH:8:4} " - fi - done - KEY_SHARE_EXTN_NR="33" - while true; do - supported_versions="" - for i in 1C 1B 1A 19 18 17; do - [[ "$drafts_offered" =~ \ 7F$i\ ]] || supported_versions+=",7f,$i" - done - [[ "$drafts_offered" =~ \ 0304\ ]] || supported_versions+=",03,04" - [[ -z "$supported_versions" ]] && break - supported_versions="00, 2b, 00, $(printf "%02x" $((${#supported_versions}/3+1))), $(printf "%02x" $((${#supported_versions}/3))) $supported_versions" - tls_sockets "04" "$TLS13_CIPHER" "" "$supported_versions" - [[ $? -eq 0 ]] || break - if [[ "$TLS_SERVER_HELLO" =~ 002B00020304 ]]; then - drafts_offered+=" 0304 " - elif [[ "$TLS_SERVER_HELLO" =~ 002B00027F1[7-9A-C] ]]; then - drafts_offered+=" ${BASH_REMATCH:8:4} " - fi - done - KEY_SHARE_EXTN_NR="$key_share_extn_nr" - if [[ -n "$drafts_offered" ]]; then - for i in 1C 1B 1A 19 18 17 16 15 14 13 12; do - if [[ "$drafts_offered" =~ \ 7F$i\ ]]; then - [[ -n "$drafts_offered_str" ]] && drafts_offered_str+=", " - drafts_offered_str+="draft $(printf "%d" 0x$i)" - fi - done - if [[ "$drafts_offered" =~ \ 0304\ ]]; then - [[ -n "$drafts_offered_str" ]] && drafts_offered_str+=", " - drafts_offered_str+="final" - fi - if [[ "$drafts_offered" =~ \ 0304\ ]]; then - pr_svrty_best "offered (OK)"; outln ": $drafts_offered_str" - fileout "$jsonID" "OK" "offered with $drafts_offered_str" - else - out "offered (OK)"; outln ": $drafts_offered_str" - fileout "$jsonID" "INFO" "offered with $drafts_offered_str" - fi - else - pr_warning "Unexpected results"; outln "$debug_recomm" - fileout "$jsonID" "WARN" "unexpected results" - fi - fi - latest_supported="0304" - latest_supported_string="TLSv1.3" - add_proto_offered tls1_3 yes - ;; - 1) pr_svrty_low "not offered" - if [[ -z $latest_supported ]]; then - outln - fileout "$jsonID" "LOW" "not offered" - else - prln_svrty_critical " -- connection failed rather than downgrading to $latest_supported_string" - fileout "$jsonID" "CRITICAL" "connection failed rather than downgrading to $latest_supported_string" - fi - add_proto_offered tls1_3 no - ;; - 2) if [[ "$DETECTED_TLS_VERSION" == 0300 ]]; then - detected_version_string="SSLv3" - elif [[ "$DETECTED_TLS_VERSION" == 03* ]]; then - detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" - fi - if [[ "$DETECTED_TLS_VERSION" == "$latest_supported" ]]; then - outln "not offered and downgraded to a weaker protocol" - fileout "$jsonID" "INFO" "not offered + downgraded to weaker protocol" - elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -lt 0x$latest_supported ]]; then - out "not offered" - prln_svrty_critical " -- server supports $latest_supported_string, but downgraded to $detected_version_string" - fileout "$jsonID" "CRITICAL" "not offered, and downgraded to $detected_version_string rather than $latest_supported_string" - elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -gt 0x0304 ]]; then - out "not offered" - prln_svrty_critical " -- server responded with higher version number ($detected_version_string) than requested by client" - fileout "$jsonID" "CRITICAL" "not offered, server responded with higher version number ($detected_version_string) than requested by client" - else - out "not offered" - prln_svrty_critical " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - fileout "$jsonID" "CRITICAL" "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - fi - add_proto_offered tls1_3 no - ;; - 3) out "not offered " - fileout "$jsonID" "INFO" "not offered" - add_proto_offered tls1_3 no - pr_warning "TLS downgraded to STARTTLS plaintext"; outln - fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext" - ;; - 4) out "likely not offered, " - fileout "$jsonID" "INFO" "not offered" - add_proto_offered tls1_3 no - pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" - fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" - ;; - 5) outln "$supported_no_ciph1" # protocol detected but no cipher --> comes from run_prototest_openssl - fileout "$jsonID" "INFO" "$supported_no_ciph1" - add_proto_offered tls1_3 yes - ;; - 7) if "$using_sockets" ; then - # can only happen in debug mode - prln_warning "strange reply, maybe a client side problem with TLS 1.3"; outln "$debug_recomm" - else - prln_local_problem "$OPENSSL doesn't support \"s_client -tls1_3\"" - fileout "$jsonID" "WARN" "not tested due to lack of local support" - fi - ((ret++)) - ;; - *) pr_fixme "unexpected value around line $((LINENO))"; outln "$debug_recomm" - ((ret++)) - ;; - esac - - debugme echo "PROTOS_OFFERED: $PROTOS_OFFERED" - if [[ ! "$PROTOS_OFFERED" =~ yes ]]; then - outln - ignore_no_or_lame "You should not proceed as no protocol was detected. If you still really really want to, say \"YES\"" "YES" - [[ $? -ne 0 ]] && exit $ERR_CLUELESS - fi - - return $ret -} - - -# list ciphers (and makes sure you have them locally configured) -# arg[1]: non-TLSv1.3 cipher list (or anything else) -# arg[2]: TLSv1.3 cipher list -# arg[3]: protocol (e.g., -ssl2) -# -listciphers() { - local -i ret - local debugname="" - local ciphers="$1" - local tls13_ciphers="$TLS13_OSSL_CIPHERS" - - [[ "$2" != ALL ]] && tls13_ciphers="$2" - "$HAS_SECLEVEL" && [[ -n "$ciphers" ]] && ciphers="@SECLEVEL=0:$1" - if "$HAS_CIPHERSUITES"; then - $OPENSSL ciphers $OSSL_CIPHERS_S $3 -ciphersuites "$tls13_ciphers" "$ciphers" &>$TMPFILE - elif [[ -n "$tls13_ciphers" ]]; then - $OPENSSL ciphers $OSSL_CIPHERS_S $3 "$tls13_ciphers:$ciphers" &>$TMPFILE - else - $OPENSSL ciphers $OSSL_CIPHERS_S $3 "$ciphers" &>$TMPFILE - fi - ret=$? - debugme cat $TMPFILE - debugname="$(sed -e s'/\!/not/g' -e 's/\:/_/g' <<< "$1")" - tmpfile_handle ${FUNCNAME[0]}.${debugname}.txt - return $ret -} - - -# argv[1]: non-TLSv1.3 cipher list to test in OpenSSL syntax -# argv[2]: TLSv1.3 cipher list to test in OpenSSL syntax -# argv[3]: string on console / HTML or "finding" -# argv[4]: rating whether ok to offer -# argv[5]: string to be appended for fileout -# argv[6]: non-SSLv2 cipher list to test (hexcodes), if using sockets -# argv[7]: SSLv2 cipher list to test (hexcodes), if using sockets -# argv[8]: true if using sockets, false if not -# argv[9]: CVE -# argv[10]: CWE -# -sub_cipherlists() { - local -i i len sclient_success=1 - local cipherlist sslv2_cipherlist detected_ssl2_ciphers - local singlespaces - local proto="" - local -i ret=0 - local jsonID="cipherlist" - local using_sockets="${8}" - local cve="${9}" - local cwe="${10}" - - pr_bold "$3 " - [[ "$OPTIMAL_PROTO" == -ssl2 ]] && proto="$OPTIMAL_PROTO" - jsonID="${jsonID}_$5" - - if "$using_sockets" || listciphers "$1" "$2" $proto; then - if ! "$using_sockets" || { "$FAST" && listciphers "$1" "$2" -tls1; }; then - for proto in -no_ssl2 -tls1_2 -tls1_1 -tls1 -ssl3; do - if [[ "$proto" == -tls1_2 ]]; then - # If $OPENSSL doesn't support TLSv1.3 or if no TLSv1.3 - # ciphers are being tested, then a TLSv1.2 ClientHello - # was tested in the first iteration. - ! "$HAS_TLS13" && continue - [[ -z "$2" ]] && continue - fi - ! "$HAS_SSL3" && [[ "$proto" == -ssl3 ]] && continue - if [[ "$proto" != -no_ssl2 ]]; then - "$FAST" && continue - [[ $(has_server_protocol "${proto:1}") -eq 1 ]] && continue - fi - $OPENSSL s_client $(s_client_options "-cipher "$1" -ciphersuites "\'$2\'" $BUGS $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI $proto") 2>$ERRFILE >$TMPFILE $ERRFILE >$TMPFILE atm ok, as sockets are preferred. If there would be a single function for testing: yes. -run_cipherlists() { - local hexc hexcode strength - local -i i - local -i ret=0 - local ossl_null_ciphers null_ciphers sslv2_null_ciphers - local ossl_anon_ciphers anon_ciphers sslv2_anon_ciphers - local ossl_exp_ciphers exp_ciphers sslv2_exp_ciphers - local ossl_low_ciphers low_ciphers sslv2_low_ciphers - local ossl_tdes_ciphers tdes_ciphers sslv2_tdes_ciphers - local ossl_obsoleted_ciphers obsoleted_ciphers - local strong_ciphers - local cwe="CWE-327" - local cwe2="CWE-310" - local cve="" - local using_sockets=true - - outln - pr_headlineln " Testing cipher categories " - outln - "$SSL_NATIVE" && using_sockets=false - - # conversion 2 byte ciphers via: echo "$@" | sed -e 's/[[:xdigit:]]\{2\},/0x&/g' -e 's/, /\n/g' | while read ci; do grep -wi $ci etc/cipher-mapping.txt; done - - ossl_null_ciphers='NULL:eNULL' - null_ciphers="c0,10, c0,06, c0,15, c0,0b, c0,01, c0,3b, c0,3a, c0,39, 00,b9, 00,b8, 00,b5, 00,b4, 00,2e, 00,2d, 00,b1, 00,b0, 00,2c, 00,3b, 00,02, 00,01, 00,82, 00,83, ff,87, 00,ff" - sslv2_null_ciphers="FF,80,10, 00,00,00" - - ossl_anon_ciphers='aNULL:ADH' - anon_ciphers="c0,19, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, c0,47, c0,5b, c0,85, c0,18, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, c0,46, c0,5a, c0,84, c0,16, 00,18, c0,17, 00,1b, 00,1a, 00,19, 00,17, c0,15, 00,ff" - sslv2_anon_ciphers="FF,80,10" - - ossl_exp_ciphers='EXPORT:!ADH:!NULL' - # grep -i EXP etc/cipher-mapping.txt - exp_ciphers="00,63, 00,62, 00,61, 00,65, 00,64, 00,60, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e, 00,17, 00,03, 00,28, 00,2b, 00,ff" - sslv2_exp_ciphers="04,00,80, 02,00,80, 00,00,00" - - ossl_low_ciphers='LOW:DES:RC2:RC4:MD5:!ADH:!EXP:!NULL:!eNULL:!AECDH' - # grep -Ew '64|56|RC2|RC4|MD5' etc/cipher-mapping.txt | grep -Ev 'Au=None|export' - low_ciphers="00,04, 00,05, 00,09, 00,0C, 00,0F, 00,12, 00,15, 00,1E, 00,20, 00,22, 00, 23, 00,24, 00,25, 00,66, 00,8A, 00,8E, 00,92, C0,02, C0,07, C0,0C, C0,11, C0,33, FF,00, FE,FE, FF,E1, 00,FF" - sslv2_low_ciphers="01,00,80, 03,00,80, 05,00,80, 06,00,40, 06,01,40, 07,00,c0, 08,00,80, FF,80,00" - - ossl_tdes_ciphers='3DES:IDEA:!aNULL:!ADH:!MD5' - # grep -Ew '3DES|IDEA' etc/cipher-mapping.txt | grep -Ev "Au=None|MD5" - tdes_ciphers="00,07, 00,0A, 00,0D, 00,10, 00,13, 00,16, 00,1F, 00,21, 00,8B, 00,8F, 00,93, C0,03, C0,08, C0,0D, C0,12, C0,1A, C0,1B, C0,1C, C0,34, FE,FF, FF,E0, 00,FF" - sslv2_tdes_ciphers="07,01,c0" - - # # Now all AES, CAMELLIA, ARIA and SEED CBC ciphers plus GOST - ossl_obsoleted_ciphers='HIGH:MEDIUM:AES:CAMELLIA:ARIA:!IDEA:!CHACHA20:!3DES:!RC2:!RC4:!AESCCM8:!AESCCM:!AESGCM:!ARIAGCM:!aNULL:!MD5' - # grep -Ew "256|128" etc/cipher-mapping.txt | grep -Ev "Au=None|AEAD|RC2|RC4|IDEA|MD5" - obsoleted_ciphers="00,2F, 00,30, 00,31, 00,32, 00,33, 00,35, 00,36, 00,37, 00,38, 00,39, 00,3C, 00,3D, 00,3E, 00,3F, 00,40, 00,41, 00,42, 00,43, 00,44, 00,45, 00,67, 00,68, 00,69, 00,6A, 00,6B, 00,84, 00,85, 00,86, 00,87, 00,88, 00,8C, 00,8D, 00,90, 00,91, 00,94, 00,95, 00,96, 00,97, 00,98, 00,99, 00,9A, 00,AE, 00,AF, 00,B2, 00,B3, 00,B6, 00,B7, 00,BA, 00,BB, 00,BC, 00,BD, 00,BE, 00,C0, 00,C1, 00,C2, 00,C3, 00,C4, C0,04, C0,05, C0,09, C0,0A, C0,0E, C0,0F, C0,13, C0,14, C0,1D, C0,1E, C0,1F, C0,20, C0,21, C0,22, C0,23, C0,24, C0,25, C0,26, C0,27, C0,28, C0,29, C0,2A, C0,35, C0,36, C0,37, C0,38, C0,3C, C0,3D, C0,3E, C0,3F, C0,40, C0,41, C0,42, C0,43, C0,44, C0,45, C0,48, C0,49, C0,4A, C0,4B, C0,4C, C0,4D, C0,4E, C0,4F, C0,64, C0,65, C0,66, C0,67, C0,68, C0,69, C0,70, C0,71, C0,72, C0,73, C0,74, C0,75, C0,76, C0,77, C0,78, C0,79, C0,94, C0,95, C0,96, C0,97, C0,98, C0,99, C0,9A, C0,9B" - # Workaround: If we use sockets and in order not to hit 131+1 ciphers we omit the GOST ciphers if SERVER_SIZE_LIMIT_BUG is true. - # This won't be supported by Cisco ACE anyway. - "$SERVER_SIZE_LIMIT_BUG" || obsoleted_ciphers="${obsoleted_ciphers}, 00,80, 00,81, FF,01, FF,02, FF,03, FF,85" - obsoleted_ciphers="${obsoleted_ciphers}, 00,FF" - - ossl_good_ciphers='AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kEECDH:!kEDH:!kDHE:!kDHEPSK:!kECDHEPSK:!aNULL' - # grep AEAD etc/cipher-mapping.txt | grep -Ev 'Au=None|TLS_ECDHE|TLS_DHE|TLS_PSK_DHE|TLSv1.3' - good_ciphers="00,9C, 00,9D, 00,A0, 00,A1, 00,A4, 00,A5, 00,A8, 00,A9, 00,AC, 00,AD, C0,2D, C0,2E, C0,31, C0,32, C0,50, C0,51, C0,54, C0,55, C0,58, C0,59, C0,5E, C0,5F, C0,62, C0,63, C0,6A, C0,6B, C0,6E, C0,6F, C0,7A, C0,7B, C0,7E, C0,7F, C0,82, C0,83, C0,88, C0,89, C0,8C, C0,8D, C0,8E, C0,8F, C0,92, C0,93, C0,9C, C0,9D, C0,A0, C0,A1, C0,A4, C0,A5, C0,A8, C0,A9, CC,AB, CC,AE, 00,FF" - - ossl_strong_ciphers='AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kPSK:!kRSAPSK:!kRSA:!kDH:!kECDH:!aNULL' - # grep AEAD etc/cipher-mapping.txt | grep -E 'TLS_ECDHE|TLS_DHE|TLS_PSK_DHE|TLSv1.3' - strong_ciphers="00,9E, 00,9F, 00,A2, 00,A3, 00,AA, 00,AB, 13,01, 13,02, 13,03, 13,04, 13,05, 16,B7, 16,B8, 16,B9, 16,BA, C0,2B, C0,2C, C0,2F, C0,30, C0,52, C0,53, C0,56, C0,57, C0,5C, C0,5D, C0,60, C0,61, C0,6C, C0,6D, C0,7C, C0,7D, C0,80, C0,81, C0,86, C0,87, C0,8A, C0,8B, C0,90, C0,91, C0,9E, C0,9F, C0,A2, C0,A3, C0,A6, C0,A7, C0,AA, C0,AB, C0,AC, C0,AD, C0,AE, C0,AF, CC,13, CC,14, CC,15, CC,A8, CC,A9, CC,AA, CC,AC, CC,AD, 00,FF" - - # argv[1]: non-TLSv1.3 cipher list to test in OpenSSL syntax - # argv[2]: TLSv1.3 cipher list to test in OpenSSL syntax - # argv[3]: string on console / HTML or "finding" - # argv[4]: rating whether ok to offer - # argv[5]: string to be appended for fileout - # argv[6]: non-SSLv2 cipher list to test (hexcodes), if using sockets - # argv[7]: SSLv2 cipher list to test (hexcodes), if using sockets - # argv[8]: true if using sockets, false if not - # argv[9]: CVE - # argv[10]: CWE - - sub_cipherlists "$ossl_null_ciphers" "" " NULL ciphers (no encryption) " 1 "NULL" "$null_ciphers" "$sslv2_null_ciphers" "$using_sockets" "$cve" "$cwe" - ret=$? - sub_cipherlists "$ossl_anon_ciphers" "" " Anonymous NULL Ciphers (no authentication) " 1 "aNULL" "$anon_ciphers" "$sslv2_anon_ciphers" "$using_sockets" "$cve" "$cwe" - ret=$((ret + $?)) - sub_cipherlists "$ossl_exp_ciphers" "" " Export ciphers (w/o ADH+NULL) " 1 "EXPORT" "$exp_ciphers" "$sslv2_exp_ciphers" "$using_sockets" "$cve" "$cwe" - ret=$((ret + $?)) - sub_cipherlists "$ossl_low_ciphers" "" " LOW: 64 Bit + DES, RC[2,4], MD5 (w/o export) " 2 "LOW" "$low_ciphers" "$sslv2_low_ciphers" "$using_sockets" "$cve" "$cwe" - ret=$((ret + $?)) - sub_cipherlists "$ossl_tdes_ciphers" "" " Triple DES Ciphers / IDEA " 3 "3DES_IDEA" "$tdes_ciphers" "$sslv2_tdes_ciphers" "$using_sockets" "$cve" "$cwe2" - ret=$((ret + $?)) - sub_cipherlists "$ossl_obsoleted_ciphers" "" " Obsoleted CBC ciphers (AES, ARIA etc.) " 4 "OBSOLETED" "$obsoleted_ciphers" "" "$using_sockets" "$cve" "$cwe2" - ret=$((ret + $?)) - sub_cipherlists "$ossl_good_ciphers" "" " Strong encryption (AEAD ciphers) with no FS " 6 "STRONG_NOFS" "$good_ciphers" "" "$using_sockets" "" "" - ret=$((ret + $?)) - sub_cipherlists "$ossl_strong_ciphers" 'ALL' " Forward Secrecy strong encryption (AEAD ciphers)" 7 "STRONG_FS" "$strong_ciphers" "" "$using_sockets" "" "" - ret=$((ret + $?)) - - outln - return $ret -} - -pr_sigalg_quality() { - local sigalg="$1" - - if [[ "$sigalg" =~ MD5 ]]; then - pr_svrty_high "$sigalg" - elif [[ "$sigalg" =~ SHA1 ]]; then - pr_svrty_low "$sigalg" - else - out "$sigalg" - fi -} - - -# The return value is an indicator of the quality of the DH key length in $1: -# 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low -# 5 = neither good nor bad, 6 = pr_svrty_good, 7 = pr_svrty_best -pr_dh_quality() { - local bits="$1" - local string="$2" - - if [[ "$bits" -le 600 ]]; then - pr_svrty_critical "$string" - return 1 - elif [[ "$bits" -le 800 ]]; then - pr_svrty_high "$string" - return 2 - elif [[ "$bits" -le 1280 ]]; then - pr_svrty_medium "$string" - return 3 - elif [[ "$bits" -ge 2048 ]]; then - pr_svrty_good "$string" - return 6 - else - out "$string" - return 5 - fi -} - -# prints out dh group=prime and in round brackets DH bits and labels it accordingly -# arg1: name of dh group, arg2=bit length -pr_dh() { - local -i quality=0 - - pr_italic "$1" - out " (" - pr_dh_quality "$2" "$2 bits" - quality=$? - out ")" - return $quality -} - -pr_ecdh_quality() { - local bits="$1" - local string="$2" - - if [[ "$bits" -le 80 ]]; then # has that ever existed? - pr_svrty_critical "$string" - elif [[ "$bits" -le 108 ]]; then # has that ever existed? - pr_svrty_high "$string" - elif [[ "$bits" -le 163 ]]; then - pr_svrty_medium "$string" - elif [[ "$bits" -le 193 ]]; then # hmm, according to https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography it should ok - pr_svrty_low "$string" # but openssl removed it https://github.com/drwetter/testssl.sh/issues/299#issuecomment-220905416 - elif [[ "$bits" -le 224 ]]; then - out "$string" - elif [[ "$bits" -gt 224 ]]; then - pr_svrty_good "$string" - else - out "$string" - fi -} - -pr_ecdh_curve_quality() { - curve="$1" - local -i bits=0 - - case "$curve" in - "sect163k1") bits=163 ;; - "sect163r1") bits=162 ;; - "sect163r2") bits=163 ;; - "sect193r1") bits=193 ;; - "sect193r2") bits=193 ;; - "sect233k1") bits=232 ;; - "sect233r1") bits=233 ;; - "sect239k1") bits=238 ;; - "sect283k1") bits=281 ;; - "sect283r1") bits=282 ;; - "sect409k1") bits=407 ;; - "sect409r1") bits=409 ;; - "sect571k1") bits=570 ;; - "sect571r1") bits=570 ;; - "secp160k1") bits=161 ;; - "secp160r1") bits=161 ;; - "secp160r2") bits=161 ;; - "secp192k1") bits=192 ;; - "prime192v1") bits=192 ;; - "secp224k1") bits=225 ;; - "secp224r1") bits=224 ;; - "secp256k1") bits=256 ;; - "prime256v1") bits=256 ;; - "secp384r1") bits=384 ;; - "secp521r1") bits=521 ;; - "brainpoolP256r1"*) bits=256 ;; - "brainpoolP384r1"*) bits=384 ;; - "brainpoolP512r1"*) bits=512 ;; - "X25519") bits=253 ;; - "X448") bits=448 ;; - esac - pr_ecdh_quality "$bits" "$curve" -} - -# Return a value that is an indicator of the quality of the cipher in $1: -# 0 = $1 is empty -# 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low -# 5 = neither good nor bad, 6 = pr_svrty_good, 7 = pr_svrty_best -# -# Please note this section isn't particular spot on. It needs to be reconsidered/redone -# SHA1, SSLv3 ciphers are some points which need to be considered. -# Hint: find out by "grep etc/cipher-mapping.txt" but it' might be be easier -# to look out Enc= and Au= or Mac= -# -get_cipher_quality() { - local cipher="$1" - local ossl_cipher - - [[ -z "$1" ]] && return 0 - - if [[ "$cipher" != TLS_* ]] && [[ "$cipher" != SSL_* ]]; then - # This must be the OpenSSL name for a cipher or for TLS 1.3 ($TLS13_OSSL_CIPHERS) - # We can ignore them however as the OpenSSL and RFC names currently match - if [[ $TLS_NR_CIPHERS -eq 0 ]]; then - # We have an OpenSSL name and can't convert it to the RFC name which is rarely - # the case, see "prepare_arrays()" and "./etc/cipher-mapping.txt" - case "$cipher" in - *NULL*|EXP*|ADH*|AECDH*|*anon*) - return 1 - ;; - *RC4*|*RC2*|*MD5|*M1) - return 2 - ;; - AES256-GCM-SHA384|AES128-GCM-SHA256|AES256-CCM*|AES128-CCM*|ARIA256-GCM-SHA384|ARIA128-GCM-SHA256) - # RSA kx and e.g. GCM isn't certainly the best - return 6 - ;; - *CBC3*|*3DES*|*IDEA*) - return 3 - ;; - *DES*) - return 2 - ;; - PSK-*GCM*|PSK-*CCM*|RSA-PSK-*GCM*|RSA-PSK-CHACHA20-POLY1305|PSK-CHACHA20-POLY1305) - # PSK kx and e.g. GCM isn't certainly the best - return 6 - ;; - DH-*GCM*|ECDH-*GCM*) - # static DH or ECDH kx and GCM isn't certainly the best - return 6 - ;; - *GCM*|*CCM*|*CHACHA20*) - return 7 - ;; #best ones - *AES*SHA*|*CAMELLIA*SHA*|*SEED*SHA*|*CBC*|*GOST*) - return 4 - ;; - *) - return 5 - ;; - esac - fi - ossl_cipher="$cipher" - cipher="$(openssl2rfc "$cipher")" - [[ -z "$cipher" ]] && cipher="$ossl_cipher" - fi - - # Now we look at the RFC cipher names. The sequence matters - as above. - case "$cipher" in - *NULL*|*EXP*|*_DES40_*|*anon*) - return 1 - ;; - *RC4*|*RC2*|*MD5|*MD5_1) - return 2 - ;; - *_DES_*) - if [[ "$cipher" =~ EDE3 ]]; then - return 3 - fi - return 2 - ;; - *CBC3*|*3DES*|*IDEA*) - return 3 - ;; - *CBC*|*GOST*) - return 4 - ;; - TLS_RSA_*|TLS_DH_*|TLS_ECDH_*|TLS_PSK_WITH_*) - # RSA, or static DH, ECDH, or PSK kx and e.g. GCM isn't certainly the best - return 6 - ;; - *GCM*|*CCM*|*CHACHA20*) - return 7 - ;; - *) - return 5 - ;; - esac -} - -# Output the severity level associated with the cipher in $1. -get_cipher_quality_severity() { - local cipher="$1" - local -i quality - - [[ -z "$1" ]] && return 0 - - get_cipher_quality "$cipher" - quality=$? - case $quality in - 1) tm_out "CRITICAL" ;; - 2) tm_out "HIGH" ;; - 3) tm_out "MEDIUM" ;; - 4) tm_out "LOW" ;; - 5) tm_out "INFO" ;; - 6|7) tm_out "OK" ;; - esac - return $quality -} - -# Print $2 based on the quality of the cipher in $1. If $2 is empty, just print $1. -# The return value is an indicator of the quality of the cipher in $1: -# 0 = $1 is empty -# 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low -# 5 = neither good nor bad, 6 = pr_svrty_good, 7 = pr_svrty_best -# -pr_cipher_quality() { - local cipher="$1" - local text="$2" - local -i quality - - [[ -z "$1" ]] && return 0 - [[ -z "$text" ]] && text="$cipher" - - get_cipher_quality "$cipher" - quality=$? - case $quality in - 1) pr_svrty_critical "$text" ;; - 2) pr_svrty_high "$text" ;; - 3) pr_svrty_medium "$text" ;; - 4) pr_svrty_low "$text" ;; - 5) out "$text" ;; - 6) pr_svrty_good "$text" ;; - 7) pr_svrty_best "$text" ;; - esac - return $quality -} - -# arg1: file with input for grepping the type of ephemeral DH key (DH ECDH) -read_dhtype_from_file() { - local temp kx - - temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$1") # extract line - kx="Kx=${temp%%,*}" - [[ "$kx" == "Kx=X25519" ]] && kx="Kx=ECDH" - [[ "$kx" == "Kx=X448" ]] && kx="Kx=ECDH" - tm_out "$kx" - return 0 -} - -# arg1: certificate file -read_sigalg_from_file() { - local sig_alg - - sig_alg="$(strip_leading_space "$($OPENSSL x509 -noout -text -in "$1" 2>/dev/null | awk -F':' '/Signature Algorithm/ { print $2; exit; }')")" - case "$sig_alg" in - 1.3.101.112|ED25519) tm_out "Ed25519" ;; - 1.3.101.113|ED448) tm_out "Ed448" ;; - *) tm_out "$sig_alg" ;; - esac - -} - - -# arg1: file with input for grepping the bit length for ECDH/DHE -# arg2: whether to print warning "old fart" or not (empty: no) -read_dhbits_from_file() { - local bits what_dh temp curve="" - local add="" - local old_fart=" (your $OPENSSL cannot show DH bits)" - - temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$1") # extract line - what_dh="${temp%%,*}" - bits="${temp##*, }" - curve="${temp#*, }" - if [[ "$curve" == "$bits" ]]; then - curve="" - else - curve="${curve%%,*}" - fi - bits="${bits/bits/}" - bits="${bits// /}" - - if [[ "$what_dh" == X25519 ]] || [[ "$what_dh" == X448 ]]; then - curve="$what_dh" - what_dh="ECDH" - fi - if [[ -z "$2" ]]; then - if [[ -n "$curve" ]]; then - debugme echo ">$HAS_DH_BITS|$what_dh($curve)|$bits<" - else - debugme echo ">$HAS_DH_BITS|$what_dh|$bits<" - fi - fi - [[ -n "$what_dh" ]] && HAS_DH_BITS=true # FIX 190 - if [[ -z "$what_dh" ]] && ! "$HAS_DH_BITS"; then - if [[ "$2" == "string" ]]; then - tm_out "$old_fart" - elif [[ -z "$2" ]]; then - pr_warning "$old_fart" - fi - return 0 - fi - if [[ "$2" == quiet ]]; then - tm_out "$bits" - return 0 - fi - [[ -z "$2" ]] && [[ -n "$bits" ]] && out ", " - if [[ $what_dh == DH ]] || [[ $what_dh == EDH ]]; then - add="bit DH" - [[ -n "$curve" ]] && add+=" ($curve)" - if [[ "$2" == string ]]; then - tm_out ", $bits $add" - else - pr_dh_quality "$bits" "$bits $add" - fi - # https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography, https://www.keylength.com/en/compare/ - elif [[ $what_dh == ECDH ]]; then - add="bit ECDH" - [[ -n "$curve" ]] && add+=" ($curve)" - if [[ "$2" == string ]]; then - tm_out ", $bits $add" - else - pr_ecdh_quality "$bits" "$bits $add" - fi - fi - return 0 -} - - -# arg1: ID or empty. If empty resumption by ticket will be tested, otherwise by ID -# return: 0: it has resumption, 1:nope, 2: nope (OpenSSL 1.1.1), 6: CLIENT_AUTH --> problem for resumption, 7: can't tell -# -# This is basically a short(?) version from Bulletproof SSL and TLS (p386). The version according to that would be e.g. -# echo | $OPENSSL s_client -connect testssl.sh:443 -servername testssl.sh -no_ssl2 -reconnect 2>&1 | grep -E 'New|Reused' -# echo | $OPENSSL s_client -connect testssl.sh:443 -servername testssl.sh -no_ssl2 -no_ticket -reconnect 2>&1 | grep -E 'New|Reused|Session-ID' -# -# FIXME: actually Ivan's version seems faster. Worth to check and since when -reconnect is a/v -# -sub_session_resumption() { - local ret ret1 ret2 - local tmpfile=$(mktemp $TEMPDIR/session_resumption.$NODEIP.XXXXXX) - local sess_data=$(mktemp $TEMPDIR/sub_session_data_resumption.$NODEIP.XXXXXX) - local -a rw_line - local protocol="$1" - - if [[ "$2" == ID ]]; then - local byID=true - local addcmd="-no_ticket" - else - local byID=false - local addcmd="" - if ! "$TLS_TICKETS"; then - return 1 - fi - fi - [[ "$CLIENT_AUTH" == required ]] && return 6 - if ! "$HAS_TLS13" && "$HAS_NO_SSL2"; then - addcmd+=" -no_ssl2" - else - protocol=${protocol/\./_} - protocol=${protocol/v/} - protocol="-$(tolower $protocol)" - # In some cases a server will not support session tickets, but will support session resumption - # by ID. In such a case, it may be more likely to support session resumption with TLSv1.2 than - # with TLSv1.3. So, if testing a server that does not support session tickets and that supports - # both TLSv1.3 and TLSv1.2 for session resumption by ID, then use a TLSv1.2 ClientHello. (Note that - # the line below assumes that if $protocol is -tls1_3, then the server either supports TLSv1.2 or - # is TLSv1.3-only. - ! "$TLS_TICKETS" && "$byID" && [[ $(has_server_protocol "tls1_2") -eq 0 ]] && protocol="-tls1_2" - addcmd+=" $protocol" - fi - - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI $addcmd -sess_out $sess_data") $tmpfile - ret1=$? - if [[ $ret1 -ne 0 ]]; then - # MacOS and LibreSSL return 1 here, that's why we need to check whether the handshake contains e.g. a certificate - if [[ ! $(<$tmpfile) =~ -----.*\ CERTIFICATE----- ]]; then - debugme echo -n "Couldn't connect #1 " - return 7 - fi - fi - if "$byID" && [[ ! "$OSSL_NAME" =~ LibreSSL ]] && \ - [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == 1.1.1* || $OSSL_VER_MAJOR == 3 ]] && \ - [[ ! -s "$sess_data" ]]; then - # it seems OpenSSL indicates no Session ID resumption by just not generating output - debugme echo -n "No session resumption byID (empty file)" - # If we want to check the presence of session data: - # [[ ! $(<$sess_data) =~ -----.*\ SSL\ SESSION\ PARAMETERS----- ]] - ret=2 - else - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI $addcmd -sess_in $sess_data") $tmpfile 2>$ERRFILE - ret2=$? - if [[ $DEBUG -ge 2 ]]; then - echo -n "$ret1, $ret2, " - [[ -s "$sess_data" ]] && echo "not empty" || echo "empty" - fi - if [[ $ret2 -ne 0 ]]; then - if [[ ! $(<$tmpfile) =~ -----.*\ CERTIFICATE----- ]]; then - debugme echo -n "Couldn't connect #2 " - return 7 - fi - fi - # "Reused" indicates session material was reused, "New": not - if grep -aq "^Reused" "$tmpfile"; then - new_sid=false - elif grep -aq "^New" "$tmpfile"; then - new_sid=true - else - debugme echo -n "Problem with 2nd ServerHello " - fi - # Now get the line and compare the numbers "read" and "written" as a second criteria. - # If the "read" number is bigger: a new session ID was probably used. - rw_line="$(awk '/^SSL handshake has read/ { print $5" "$(NF-1) }' "$tmpfile" )" - rw_line=($rw_line) - if [[ "${rw_line[0]}" -gt "${rw_line[1]}" ]]; then - new_sid2=true - else - new_sid2=false - fi - debugme echo "${rw_line[0]}, ${rw_line[1]}" - - if "$new_sid2" && "$new_sid"; then - debugme echo -n "No session resumption " - ret=1 - elif ! "$new_sid2" && ! "$new_sid"; then - debugme echo -n "Session resumption " - ret=0 - else - debugme echo -n "unclear status: $ret1, $ret2, $new_sid, $new_sid2 -- " - ret=5 - fi - if [[ $DEBUG -ge 2 ]]; then - "$byID" && echo "byID" || echo "by ticket" - fi - fi - "$byID" && \ - tmpfile_handle ${FUNCNAME[0]}.byID.log $tmpfile || \ - tmpfile_handle ${FUNCNAME[0]}.byticket.log $tmpfile - return $ret -} - -run_server_preference() { - local cipher1="" cipher2="" tls13_cipher1="" tls13_cipher2="" default_proto="" - local default_cipher="" ciph - local limitedsense="" supported_sslv2_ciphers - local proto_ossl proto_txt proto_hex cipherlist i - local -i ret=0 j sclient_success - local list_fwd="DHE-RSA-SEED-SHA:SEED-SHA:DES-CBC3-SHA:RC4-MD5:DES-CBC-SHA:RC4-SHA:AES128-SHA:AES128-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:AES256-SHA256:ECDHE-RSA-DES-CBC3-SHA:ECDHE-RSA-AES128-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:ADH-AES256-GCM-SHA384:AECDH-AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-AES128-SHA" - local list_reverse="ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-RC4-SHA:AECDH-AES128-SHA:ADH-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-DES-CBC3-SHA:AES256-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-DES-CBC3-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:AES256-SHA:AES128-SHA256:AES128-SHA:RC4-SHA:DES-CBC-SHA:RC4-MD5:DES-CBC3-SHA:SEED-SHA:DHE-RSA-SEED-SHA" - tls_list_fwd="c0,2c, c0,30, 00,9f, cc,a9, cc,a8, cc,aa, c0,2b, c0,2f, 00,9e, c0,24, c0,28, 00,6b, c0,23, c0,27, 00,67, c0,0a, 00,04, 00,05, 00,09, 00,0a, 00,9a, 00,96, - c0,14, 00,39, c0,09, c0,13, 00,33, 00,9d, 00,9c, 13,01, 13,02, 13,03, 13,04, 13,05, 00,3d, 00,3c, 00,35, 00,2f, 00,ff" - tls_list_rev="00,2f, 00,35, 00,3c, 00,3d, 13,05, 13,04, 13,03, 13,02, 13,01, 00,9c, 00,9d, 00,33, c0,13, c0,09, 00,39, c0,14, 00,96, 00,9a, 00,0a, 00,09, 00,05, 00,04, - c0,0a, 00,67, c0,27, c0,23, 00,6b, c0,28, c0,24, 00,9e, c0,2f, c0,2b, cc,aa, cc,a8, cc,a9, 00,9f, c0,30, c0,2c, 00,ff" - local has_cipher_order=false has_tls13_cipher_order=false - local addcmd="" addcmd2="" - local using_sockets=true - local jsonID="cipher_order" fileout_msg="" fileout_rating="" terminal_msg="" - local cwe="CWE-310" - local cve="" - - "$SSL_NATIVE" && using_sockets=false - - outln - pr_headlineln " Testing server's cipher preferences " - outln - - if [[ "$OPTIMAL_PROTO" == -ssl2 ]]; then - addcmd="$OPTIMAL_PROTO" - else - # the supplied openssl will send an SSLv2 ClientHello if $SNI is empty - # and the -no_ssl2 isn't provided. - addcmd="-no_ssl2 $SNI" - fi - - # Determine negotiated protocol upfront - sclient_success=1 - if "$using_sockets" && [[ $(has_server_protocol "tls1_3") -ne 1 ]]; then - # Send similar list of cipher suites as OpenSSL 1.1.1 does - tls_sockets "04" \ - "c0,2c, c0,30, 00,9f, cc,a9, cc,a8, cc,aa, c0,2b, c0,2f, 00,9a, 00,96, - 00,9e, c0,24, c0,28, 00,6b, c0,23, c0,27, 00,67, c0,0a, - c0,14, 00,39, c0,09, c0,13, 00,33, 00,9d, 00,9c, 13,02, - 13,03, 13,01, 13,04, 13,05, 00,3d, 00,3c, 00,35, 00,2f, 00,ff" \ - "ephemeralkey" - sclient_success=$? - if [[ $sclient_success -eq 0 ]]; then - add_proto_offered tls1_3 yes - elif [[ $sclient_success -eq 2 ]]; then - sclient_success=0 # 2: downgraded - case $DETECTED_TLS_VERSION in - 0303) add_proto_offered tls1_2 yes ;; - 0302) add_proto_offered tls1_1 yes ;; - 0301) add_proto_offered tls1 yes ;; - 0300) add_proto_offered ssl3 yes ;; - esac - fi - if [[ $sclient_success -eq 0 ]] ; then - cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt" - cipher0=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt") - fi - fi - if [[ $sclient_success -ne 0 ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd") >$ERRFILE >"$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt" - if sclient_connect_successful $? "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt"; then - cipher0=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt") - debugme tm_out "0 --> $cipher0\n" - else - # 2 second try with $OPTIMAL_PROTO especially for intolerant IIS6 servers: - $OPENSSL s_client $(s_client_options "$STARTTLS $OPTIMAL_PROTO $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$ERRFILE >"$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt" - if sclient_connect_successful $? "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt"; then - cipher0=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt") - debugme tm_out "0 --> $cipher0\n" - else - pr_warning "Handshake error!" - ret=1 - fi - fi - fi - [[ $ret -eq 0 ]] && default_proto=$(get_protocol "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt") - [[ "$default_proto" == TLSv1.0 ]] && default_proto="TLSv1" - # debugme tm_out " --> $default_proto\n" - - # Some servers don't have a TLS 1.3 cipher order, see #1163 - if [[ "$default_proto" == TLSv1.3 ]]; then - tls_sockets "04" "13,05, 13,04, 13,03, 13,02, 13,01, 00,ff" - [[ $? -ne 0 ]] && ret=1 && prln_fixme "something weird happened around line $((LINENO - 1))" - cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE - tls13_cipher1=$(get_cipher $TMPFILE) - debugme tm_out "TLS 1.3: --> $tls13_cipher1\n" - tls_sockets "04" "13,01, 13,02, 13,03, 13,04, 13,05, 00,ff" - [[ $? -ne 0 ]] && ret=1 && prln_fixme "something weird happened around line $((LINENO - 1))" - cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE - tls13_cipher2=$(get_cipher $TMPFILE) - debugme tm_out "TLS 1.3: --> $tls13_cipher2\n" - - [[ $tls13_cipher1 == $tls13_cipher2 ]] && has_tls13_cipher_order=true - fi - # Check whether the server has a cipher order for SSLv3 - TLSv1.2 - if [[ $(has_server_protocol "tls1_2") -ne 0 ]] && [[ $(has_server_protocol "tls1_1") -ne 0 ]] && \ - [[ $(has_server_protocol "tls1") -ne 0 ]] && [[ $(has_server_protocol "ssl3") -ne 0 ]]; then - # Based on testing performed by determine_optimal_sockets_params(), it is believed that - # this server does not offer SSLv3 - TLSv1.2. - has_cipher_order="$has_tls13_cipher_order" - elif [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then - if [[ -n "$STARTTLS_OPTIMAL_PROTO" ]]; then - [[ ! "$STARTTLS_OPTIMAL_PROTO" =~ ssl ]] && addcmd2="$SNI" - [[ "$STARTTLS_OPTIMAL_PROTO" != -tls1_3 ]] && addcmd2+=" $STARTTLS_OPTIMAL_PROTO" - else - addcmd2="-no_ssl2 $SNI" - fi - [[ $DEBUG -ge 4 ]] && echo -e "\n Forward: ${list_fwd}" - $OPENSSL s_client $(s_client_options "$STARTTLS -cipher $list_fwd $BUGS -connect $NODEIP:$PORT $PROXY $addcmd2") $ERRFILE >$TMPFILE - if ! sclient_connect_successful $? $TMPFILE; then - list_fwd="$(actually_supported_osslciphers $list_fwd '' '-no_ssl2')" - pr_warning "no matching cipher in this list found (pls report this): " - outln "$list_fwd . " - fileout "$jsonID" "WARN" "Could not determine server cipher order, no matching cipher in list found (pls report this): $list_fwd" - ret=1 - # we assume the problem is with testing here but it could be also the server side - else - cipher1=$(get_cipher $TMPFILE) # cipher1 from 1st serverhello - debugme tm_out "1 --> $cipher1\n" - - # second client hello with reverse list - [[ $DEBUG -ge 4 ]] && echo -e "\n Reverse: ${list_reverse}" - $OPENSSL s_client $(s_client_options "$STARTTLS -cipher $list_reverse $BUGS -connect $NODEIP:$PORT $PROXY $addcmd2") >$ERRFILE >$TMPFILE - # first handshake worked above so no error handling here - cipher2=$(get_cipher $TMPFILE) # cipher2 from 2nd serverhello - debugme tm_out "2 --> $cipher2\n" - - [[ $cipher1 == $cipher2 ]] && has_cipher_order=true - fi - fi - debugme echo "has_cipher_order: $has_cipher_order" - debugme echo "has_tls13_cipher_order: $has_tls13_cipher_order" - - # restore file from above - [[ "$default_proto" == TLSv1.3 ]] && cp "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt" $TMPFILE - if [[ "$default_proto" == TLSv1.3 ]] || [[ -n "$cipher2" ]]; then - cipher1=$(get_cipher $TMPFILE) - tmpfile_handle ${FUNCNAME[0]}.txt - fi - - # Sanity check: Handshake with no ciphers and one with forward list didn't overlap - if [[ $ret -eq 0 ]] && [[ "$cipher0" != $cipher1 ]]; then - limitedsense=" (matching cipher in list missing)" - fi - - if [[ -n "$cipher1" ]]; then - ciph="$cipher1" - else - ciph="$cipher0" - cp "$TEMPDIR/$NODEIP.parse_tls13_serverhello.txt" $TMPFILE - tmpfile_handle ${FUNCNAME[0]}.txt - fi - if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]] && [[ "$ciph" == TLS_* || "$ciph" == SSL_* ]]; then - default_cipher="$(rfc2openssl "$ciph")" - elif [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]] && [[ "$ciph" != TLS_* ]] && [[ "$ciph" != SSL_* ]]; then - default_cipher="$(openssl2rfc "$ciph")" - fi - [[ -z "$default_cipher" ]] && default_cipher="$ciph" - - "$FAST" && using_sockets=false - [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false - - neat_header - while read proto_ossl proto_hex proto_txt; do - pr_underline "$(printf -- "%b" "$proto_txt")" - if [[ $(has_server_protocol "$proto_ossl") -eq 1 ]]; then - outln "\n - " - continue - fi - # TODO: Also the fact that a protocol is not supported seems not to be saved by cipher_pref_check() - # (./testssl.sh --wide -p -P -E vs ./testssl.sh --wide -P -E ) - if [[ $proto_ossl == ssl2 ]] || \ - { [[ $proto_ossl != tls1_3 ]] && ! "$has_cipher_order"; } || \ - { [[ $proto_ossl == tls1_3 ]] && ! "$has_tls13_cipher_order"; }; then - if [[ -n "$cipher2" ]] && [[ $proto_ossl != ssl2 ]]; then - ciphers_by_strength "-$proto_ossl" "$proto_hex" "$proto_txt" "$using_sockets" "true" "true" - else - ciphers_by_strength "-$proto_ossl" "$proto_hex" "$proto_txt" "$using_sockets" "true" "false" - fi - else - cipher_pref_check "$proto_ossl" "$proto_hex" "$proto_txt" "$using_sockets" "true" - fi - done <<< "$(tm_out " ssl2 22 SSLv2\n ssl3 00 SSLv3\n tls1 01 TLSv1\n tls1_1 02 TLSv1.1\n tls1_2 03 TLSv1.2\n tls1_3 04 TLSv1.3\n")" - outln - - pr_bold " Has server cipher order? " - jsonID="cipher_order" - case $NO_CIPHER_ORDER_LEVEL in - 5) fileout_rating="INFO" ;; - 4) fileout_rating="LOW" ;; - 3) fileout_rating="MEDIUM" ;; - 2) fileout_rating="HIGH" ;; - 1) fileout_rating="CRITICAL" ;; - esac - if "$TLS13_ONLY" && ! "$has_tls13_cipher_order"; then - terminal_msg="no (TLS 1.3 only)" - limitedsense=" (limited sense as client will pick)" - fileout_msg="not a cipher order for TLS 1.3 configured" - elif ! "$TLS13_ONLY" && [[ -z "$cipher2" ]]; then - pr_warning "unable to determine" - elif ! "$has_cipher_order" && ! "$has_tls13_cipher_order"; then - # server used the different ends (ciphers) from the client hello - terminal_msg="no (NOT ok)" - [[ "$fileout_rating" == INFO ]] && terminal_msg="no" - limitedsense=" (limited sense as client will pick)" - fileout_msg="NOT a cipher order configured" - elif "$has_cipher_order" && ! "$has_tls13_cipher_order" && [[ "$default_proto" == TLSv1.3 ]]; then - if [[ $NO_CIPHER_ORDER_LEVEL -eq 5 ]]; then - pr_svrty_good "yes (OK)"; out " -- only for < TLS 1.3" - fileout "$jsonID" "OK" "server -- TLS 1.3 client determined" - else - # The server does not enforce a cipher order for TLS 1.3 and it - # accepts some lower quality TLS 1.3 ciphers. - terminal_msg="only for < TLS 1.3" - fileout_msg="server -- TLS 1.3 client determined" - fi - elif ! "$has_cipher_order" && "$has_tls13_cipher_order"; then - case "$fileout_rating" in - "INFO") - out "only for TLS 1.3" - fileout "$jsonID" "INFO" "server -- < TLS 1.3 client determined" - ;; - "LOW") - pr_svrty_low "no (NOT ok)"; out " -- only for TLS 1.3" - fileout "$jsonID" "LOW" "server -- < TLS 1.3 client determined" - ;; - "MEDIUM") - pr_svrty_medium "no (NOT ok)"; out " -- only for TLS 1.3" - fileout "$jsonID" "MEDIUM" "server -- < TLS 1.3 client determined" - ;; - "HIGH") - pr_svrty_high "no (NOT ok)"; out " -- only for TLS 1.3" - fileout "$jsonID" "HIGH" "server -- < TLS 1.3 client determined" - ;; - "CRITICAL") - pr_svrty_critical "no (NOT ok)"; out " -- only for TLS 1.3" - fileout "$jsonID" "CRITICAL" "server -- < TLS 1.3 client determined" - ;; - esac - else - if "$has_tls13_cipher_order"; then - if "$TLS13_ONLY"; then - out "yes (TLS 1.3 only)" - fileout "$jsonID" "INFO" "server (TLS 1.3)" - else - pr_svrty_best "yes (OK)" - out " -- TLS 1.3 and below" - fileout "$jsonID" "OK" "server" - fi - else - # we don't have TLS 1.3 at all - pr_svrty_best "yes (OK)" - fileout "$jsonID" "OK" "server" - fi - fi - if [[ -n "$fileout_msg" ]]; then - case "$fileout_rating" in - "INFO") out "$terminal_msg" ;; - "OK") pr_svrty_good "$terminal_msg" ;; - "LOW") pr_svrty_low "$terminal_msg" ;; - "MEDIUM") pr_svrty_medium "$terminal_msg" ;; - "HIGH") pr_svrty_high "$terminal_msg" ;; - "CRITICAL") pr_svrty_critical "$terminal_msg" ;; - esac - fileout "$jsonID" "$fileout_rating" "$fileout_msg" - fi - outln - - if [[ "$cipher0" != $cipher1 ]]; then - pr_warning " -- inconclusive test, matching cipher in list missing" - outln ", better see above" - #FIXME: This is ugly but the best we can do before rewrite this section - else - outln "$limitedsense" - fi - return $ret - # end of run_server_preference() -} - -# arg1: true if the list that is returned does not need to be ordered by preference. -check_tls12_pref() { - local unordered_list_ok="$1" - local chacha20_ciphers="" non_chacha20_ciphers="" - local batchremoved="-CAMELLIA:-IDEA:-KRB5:-PSK:-SRP:-aNULL:-eNULL" - local batchremoved_success=false - local tested_cipher="" cipher ciphers_to_test - local order="" - local -i nr_ciphers_found_r1=0 nr_ciphers_found_r2=0 - - # Place ChaCha20 ciphers at the end of the list to avoid accidentally - # triggering the server's PrioritizeChaCha setting. - ciphers_to_test="$(actually_supported_osslciphers "ALL:$batchremoved" "" "")" - for cipher in $(colon_to_spaces "$ciphers_to_test"); do - [[ "$cipher" =~ CHACHA20 ]] && chacha20_ciphers+="$cipher:" || non_chacha20_ciphers+="$cipher:" - done - ciphers_to_test="$non_chacha20_ciphers$chacha20_ciphers" - ciphers_to_test="${ciphers_to_test%:}" - - while true; do - $OPENSSL s_client $(s_client_options "$STARTTLS -tls1_2 $BUGS -cipher "$ciphers_to_test$tested_cipher" -connect $NODEIP:$PORT $PROXY $SNI") >$ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE ; then - cipher=$(get_cipher $TMPFILE) - order+=" $cipher" - tested_cipher="$tested_cipher:-$cipher" - nr_ciphers_found_r1+=1 - "$FAST" && break - else - debugme tmln_out "A: $tested_cipher" - break - fi - done - batchremoved="${batchremoved//-/}" - while true; do - # no ciphers from "ALL$tested_cipher:$batchremoved" left - # now we check $batchremoved, and remove the minus signs first: - $OPENSSL s_client $(s_client_options "$STARTTLS -tls1_2 $BUGS -cipher "$batchremoved" -connect $NODEIP:$PORT $PROXY $SNI") >$ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE ; then - batchremoved_success=true # signals that we have some of those ciphers and need to put everything together later on - cipher=$(get_cipher $TMPFILE) - order+=" $cipher" - batchremoved="$batchremoved:-$cipher" - nr_ciphers_found_r1+=1 - debugme tmln_out "B1: $batchremoved" - "$FAST" && break - else - debugme tmln_out "B2: $batchremoved" - break - # nothing left with batchremoved ciphers, we need to put everything together - fi - done - - if "$batchremoved_success" && ! "$unordered_list_ok"; then - # now we combine the two cipher sets from both while loops - - # Place ChaCha20 ciphers at the end of the list to avoid accidentally - # triggering the server's PrioritizeChaCha setting. - chacha20_ciphers=""; non_chacha20_ciphers="" - for cipher in $order; do - [[ "$cipher" =~ CHACHA20 ]] && chacha20_ciphers+="$cipher " || non_chacha20_ciphers+="$cipher " - done - combined_ciphers="$non_chacha20_ciphers$chacha20_ciphers" - order="" ; tested_cipher="" - while true; do - ciphers_to_test="" - for cipher in $combined_ciphers; do - [[ ! "$tested_cipher:" =~ :-$cipher: ]] && ciphers_to_test+=":$cipher" - done - [[ -z "$ciphers_to_test" ]] && break - $OPENSSL s_client $(s_client_options "$STARTTLS -tls1_2 $BUGS -cipher "${ciphers_to_test:1}" -connect $NODEIP:$PORT $PROXY $SNI") >$ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE ; then - cipher=$(get_cipher $TMPFILE) - order+=" $cipher" - tested_cipher="$tested_cipher:-$cipher" - nr_ciphers_found_r2+=1 - "$FAST" && break - else - # This shouldn't happen. - break - fi - done - if "$FAST" && [[ $nr_ciphers_found_r2 -ne 1 ]]; then - prln_fixme "something weird happened around line $((LINENO - 14))" - return 1 - elif ! "$FAST" && [[ $nr_ciphers_found_r2 -ne $nr_ciphers_found_r1 ]]; then - prln_fixme "something weird happened around line $((LINENO - 16))" - return 1 - fi - fi - tm_out "$order" - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - -# At the moment only called from run_server_preference() -cipher_pref_check() { - local proto="$1" proto_hex="$2" proto_text="$3" - local using_sockets="$4" - local wide="$5" # at the moment always = true - local tested_cipher cipher order="" rfc_cipher rfc_order - local -i i nr_ciphers nr_nonossl_ciphers num_bundles bundle_size bundle end_of_bundle success - local -i nr_ciphers_found - local hexc ciphers_to_test cipher_list="" chacha20_ciphers non_chacha20_ciphers - local first_cipher first_chacha_cipher - local -a normalized_hexcode ciph kx enc export2 sigalg - local -a rfc_ciph hexcode ciphers_found ciphers_found2 - local -a -i index - local ciphers_found_with_sockets=false prioritize_chacha=false - - if [[ $proto == ssl3 ]] && ! "$HAS_SSL3" && ! "$using_sockets"; then - outln - prln_local_problem "$OPENSSL doesn't support \"s_client -ssl3\""; - return 0 - fi - if [[ $proto == tls1_3 ]] && ! "$HAS_TLS13" && ! "$using_sockets"; then - outln - prln_local_problem "$OPENSSL doesn't support \"s_client -tls1_3\""; - return 0 - fi - - if { [[ $proto != tls1_3 ]] || "$HAS_TLS13"; } && { [[ $proto != ssl3 ]] || "$HAS_SSL3"; }; then - if [[ $proto == tls1_2 ]] && "$SERVER_SIZE_LIMIT_BUG" && \ - [[ "$(count_ciphers "$(actually_supported_osslciphers "ALL:COMPLEMENTOFALL" "" "")")" -gt 127 ]]; then - order="$(check_tls12_pref "$wide")" - [[ "${order:0:1}" == \ ]] && order="${order:1}" - cipher_list="$order" - fi - if "$wide" || [[ -z "$order" ]]; then - # Place ChaCha20 ciphers at the end of the list to avoid accidentally - # triggering the server's PrioritizeChaCha setting. - chacha20_ciphers=""; non_chacha20_ciphers="" - if [[ $proto == tls1_3 ]]; then - cipher_list="$(colon_to_spaces "$TLS13_OSSL_CIPHERS")" - elif [[ -z "$cipher_list" ]]; then - cipher_list="$(colon_to_spaces "$(actually_supported_osslciphers "ALL:COMPLEMENTOFALL" "" "")")" - fi - for cipher in $cipher_list; do - [[ "$cipher" =~ CHACHA20 ]] && chacha20_ciphers+="$cipher " || non_chacha20_ciphers+="$cipher " - done - cipher_list="$non_chacha20_ciphers $chacha20_ciphers" - - tested_cipher=""; order=""; nr_ciphers_found=0 - while true; do - ciphers_to_test="" - for cipher in $cipher_list; do - [[ ! "$tested_cipher:" =~ :-$cipher: ]] && ciphers_to_test+=":$cipher" - done - [[ -z "$ciphers_to_test" ]] && break - if [[ $proto != tls1_3 ]]; then - ciphers_to_test="-cipher ${ciphers_to_test:1}" - else - ciphers_to_test="-ciphersuites ${ciphers_to_test:1}" - fi - $OPENSSL s_client $(s_client_options "$STARTTLS -"$proto" $BUGS $ciphers_to_test -connect $NODEIP:$PORT $PROXY $SNI") >$ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE || break - cipher=$(get_cipher $TMPFILE) - [[ -z "$cipher" ]] && break - order+="$cipher " - tested_cipher+=":-"$cipher - "$FAST" && break - if "$wide"; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$cipher" == ${TLS_CIPHER_OSSL_NAME[i]} ]] && break - done - [[ $i -eq $TLS_NR_CIPHERS ]] && continue - normalized_hexcode[nr_ciphers_found]="$(normalize_ciphercode "${TLS_CIPHER_HEXCODE[i]}")" - ciph[nr_ciphers_found]="${TLS_CIPHER_OSSL_NAME[i]}" - kx[nr_ciphers_found]="${TLS_CIPHER_KX[i]}" - [[ $proto == tls1_3 ]] && kx[nr_ciphers_found]="$(read_dhtype_from_file $TMPFILE)" - if [[ ${kx[nr_ciphers_found]} == Kx=ECDH ]] || [[ ${kx[nr_ciphers_found]} == Kx=DH ]] || [[ ${kx[nr_ciphers_found]} == Kx=EDH ]]; then - kx[nr_ciphers_found]+=" $(read_dhbits_from_file "$TMPFILE" quiet)" - fi - enc[nr_ciphers_found]="${TLS_CIPHER_ENC[i]}" - export2[nr_ciphers_found]="${TLS_CIPHER_EXPORT[i]}" - sigalg[nr_ciphers_found]="" - "$SHOW_SIGALGO" && grep -qe '-----BEGIN CERTIFICATE-----' $TMPFILE && \ - sigalg[nr_ciphers_found]="$(read_sigalg_from_file "$TMPFILE")" - nr_ciphers_found+=1 - fi - done - fi - fi - - nr_nonossl_ciphers=0 - if "$using_sockets"; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - ciphers_found[i]=false - hexc="${TLS_CIPHER_HEXCODE[i]}" - if [[ ${#hexc} -eq 9 ]]; then - if [[ " $order " =~ \ ${TLS_CIPHER_OSSL_NAME[i]}\ ]]; then - ciphers_found[i]=true - else - ciphers_found2[nr_nonossl_ciphers]=false - hexcode[nr_nonossl_ciphers]="${hexc:2:2},${hexc:7:2}" - rfc_ciph[nr_nonossl_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" - index[nr_nonossl_ciphers]=$i - # Only test ciphers that are relevant to the protocol. - if [[ $proto == tls1_3 ]]; then - [[ "${hexc:2:2}" == 13 ]] && nr_nonossl_ciphers+=1 - elif [[ $proto == tls1_2 ]]; then - [[ "${hexc:2:2}" != 13 ]] && nr_nonossl_ciphers+=1 - elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA256 ]] && \ - [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA384 ]] && \ - [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM ]] && \ - [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM_8 ]]; then - nr_nonossl_ciphers+=1 - fi - fi - fi - done - fi - - if [[ $nr_nonossl_ciphers -eq 0 ]]; then - num_bundles=0 - elif [[ $proto != tls1_2 ]] || ! "$SERVER_SIZE_LIMIT_BUG"; then - num_bundles=1 - bundle_size=$nr_nonossl_ciphers - else - num_bundles=$nr_nonossl_ciphers/128 - [[ $((nr_nonossl_ciphers%128)) -ne 0 ]] && num_bundles+=1 - - bundle_size=$nr_nonossl_ciphers/$num_bundles - [[ $((nr_nonossl_ciphers%num_bundles)) -ne 0 ]] && bundle_size+=1 - fi - - for (( bundle=0; bundle < num_bundles; bundle++ )); do - end_of_bundle=$(( (bundle+1)*bundle_size )) - [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers - while true; do - ciphers_to_test="" - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode[i]}" - done - [[ -z "$ciphers_to_test" ]] && break - tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" - [[ $? -ne 0 ]] && break - cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do - [[ "$cipher" == ${rfc_ciph[i]} ]] && ciphers_found2[i]=true && break - done - i=${index[i]} - ciphers_found[i]=true - ciphers_found_with_sockets=true - if [[ $proto != tls1_2 ]] || ! "$SERVER_SIZE_LIMIT_BUG"; then - # Throw out the results found so far and start over using just sockets - bundle=$num_bundles - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - ciphers_found[i]=true - done - break - fi - done - done - - # If additional ciphers were found using sockets and there is no - # SERVER_SIZE_LIMIT_BUG, then just use sockets to find the cipher order. - # If there is a SERVER_SIZE_LIMIT_BUG, then use sockets to find the cipher - # order, but starting with the list of ciphers supported by the server. - if "$ciphers_found_with_sockets"; then - # Create an array of the ciphers to test with any ChaCha20 - # listed last in order to avoid accidentally triggering the - # server's PriorizeChaCha setting. - order=""; nr_ciphers=0; nr_ciphers_found=0 - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CHACHA20 ]] && continue - [[ "${TLS_CIPHER_OSSL_NAME[i]}" =~ CHACHA20 ]] && continue - hexc="${TLS_CIPHER_HEXCODE[i]}" - if "${ciphers_found[i]}" && [[ ${#hexc} -eq 9 ]]; then - ciphers_found2[nr_ciphers]=false - hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" - rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" - if [[ $proto == tls1_3 ]]; then - [[ "${hexc:2:2}" == 13 ]] && nr_ciphers+=1 - elif [[ $proto == tls1_2 ]]; then - [[ "${hexc:2:2}" != 13 ]] && nr_ciphers+=1 - elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA256 ]] && \ - [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA384 ]] && \ - [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM ]] && \ - [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM_8 ]]; then - nr_ciphers+=1 - fi - fi - done - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CHACHA20 ]] || [[ "${TLS_CIPHER_OSSL_NAME[i]}" =~ CHACHA20 ]] || continue - hexc="${TLS_CIPHER_HEXCODE[i]}" - if "${ciphers_found[i]}" && [[ ${#hexc} -eq 9 ]]; then - ciphers_found2[nr_ciphers]=false - hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" - rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" - if [[ $proto == tls1_3 ]]; then - [[ "${hexc:2:2}" == 13 ]] && nr_ciphers+=1 - elif [[ $proto == tls1_2 ]]; then - [[ "${hexc:2:2}" != 13 ]] && nr_ciphers+=1 - elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA256 ]] && \ - [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA384 ]] && \ - [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM ]] && \ - [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM_8 ]]; then - nr_ciphers+=1 - fi - fi - done - while true; do - ciphers_to_test="" - for (( i=0; i < nr_ciphers; i++ )); do - ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode[i]}" - done - [[ -z "$ciphers_to_test" ]] && break - if "$wide" && "$SHOW_SIGALGO"; then - tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "all" - else - tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" - fi - [[ $? -ne 0 ]] && break - cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - for (( i=0; i < nr_ciphers; i++ )); do - [[ "$cipher" == ${rfc_ciph[i]} ]] && ciphers_found2[i]=true && break - done - if "$wide"; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$cipher" == ${TLS_CIPHER_RFC_NAME[i]} ]] && break - done - [[ $i -eq $TLS_NR_CIPHERS ]] && continue - normalized_hexcode[nr_ciphers_found]="$(normalize_ciphercode "${TLS_CIPHER_HEXCODE[i]}")" - ciph[nr_ciphers_found]="${TLS_CIPHER_OSSL_NAME[i]}" - kx[nr_ciphers_found]="${TLS_CIPHER_KX[i]}" - [[ $proto == tls1_3 ]] && kx[nr_ciphers_found]="$(read_dhtype_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - if [[ ${kx[nr_ciphers_found]} == Kx=ECDH ]] || [[ ${kx[nr_ciphers_found]} == Kx=DH ]] || [[ ${kx[nr_ciphers_found]} == Kx=EDH ]]; then - kx[nr_ciphers_found]+=" $(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet)" - fi - enc[nr_ciphers_found]="${TLS_CIPHER_ENC[i]}" - export2[nr_ciphers_found]="${TLS_CIPHER_EXPORT[i]}" - sigalg[nr_ciphers_found]="" - "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \ - sigalg[nr_ciphers_found]="$(read_sigalg_from_file "$HOSTCERT")" - nr_ciphers_found+=1 - fi - if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]] && [[ $TLS_NR_CIPHERS -ne 0 ]]; then - cipher="$(rfc2openssl "$cipher")" - # If there is no OpenSSL name for the cipher, then use the RFC name - [[ -z "$cipher" ]] && cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - fi - order+="$cipher " - done - elif [[ -n "$order" ]] && [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then - rfc_order="" - while read -d " " cipher; do - rfc_cipher="$(openssl2rfc "$cipher")" - if [[ -n "$rfc_cipher" ]]; then - rfc_order+="$rfc_cipher " - else - rfc_order+="$cipher " - fi - done <<< "$order" - order="$rfc_order" - fi - - # If the server supports at least one ChaCha20 cipher that is less - # preferred than a non-ChaCha20 cipher, then check if the server is - # configured to prioritize ChaCha20 if that cipher is listed first - # in the ClientHello. - first_cipher=""; first_chacha_cipher="" - for cipher in $order; do - [[ ! "$cipher" =~ CHACHA20 ]] && first_cipher="$cipher" && break - done - if [[ -n "$first_cipher" ]]; then - # Search for first ChaCha20 cipher that comes after $first_cipher in $order. - for first_chacha_cipher in ${order#*$first_cipher}; do - [[ "$first_chacha_cipher" =~ CHACHA20 ]] && break - done - fi - [[ ! "${first_chacha_cipher}" =~ CHACHA20 ]] && first_chacha_cipher="" - if [[ -n "$first_cipher" ]] && [[ -n "$first_chacha_cipher" ]]; then - # $first_cipher is the first non-ChaCha20 cipher in $order and - # $first_chacha_cipher is the first ChaCha20 that comes after - # $first_cipher in $order. Check to see if the server will select - # $first_chacha_cipher if it appears before $first_cipher in the - # ClientHello. - if "$ciphers_found_with_sockets"; then - if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then - first_cipher="$(rfc2hexcode "$first_cipher")" - first_chacha_cipher="$(rfc2hexcode "$first_chacha_cipher")" - else - first_cipher="$(openssl2hexcode "$first_cipher")" - first_chacha_cipher="$(openssl2hexcode "$first_chacha_cipher")" - fi - first_cipher="${first_cipher:2:2},${first_cipher:7:2}" - first_chacha_cipher="${first_chacha_cipher:2:2},${first_chacha_cipher:7:2}" - tls_sockets "$proto_hex" "$first_chacha_cipher, $first_cipher, 00,ff" "ephemeralkey" - if [[ $? -eq 0 ]]; then - cipher="$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - [[ "$cipher" =~ CHACHA20 ]] && prioritize_chacha=true - else - pr_fixme "something weird happened around line $((LINENO - 5)) " - fi - else - if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then - first_cipher="$(rfc2openssl "$first_cipher")" - first_chacha_cipher="$(rfc2openssl "$first_chacha_cipher")" - fi - if [[ $proto != tls1_3 ]]; then - ciphers_to_test="-cipher $first_chacha_cipher:$first_cipher" - else - ciphers_to_test="-ciphersuites $first_chacha_cipher:$first_cipher" - fi - $OPENSSL s_client $(s_client_options "$STARTTLS -"$proto" $BUGS $ciphers_to_test -connect $NODEIP:$PORT $PROXY $SNI") >$ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE; then - cipher="$(get_cipher $TMPFILE)" - [[ "$cipher" =~ CHACHA20 ]] && prioritize_chacha=true - else - pr_fixme "something weird happened around line $((LINENO - 5)) " - fi - fi - fi - if "$prioritize_chacha"; then - outln " (server order -- server prioritizes ChaCha ciphers when preferred by clients)" - fileout "cipher_order-${proto}" "OK" "server -- server prioritizes ChaCha ciphers when preferred by clients" - elif [[ -n "$order" ]]; then - outln " (server order)" - fileout "cipher_order-${proto}" "OK" "server" - else - outln - fi - if [[ -n "$order" ]]; then - add_proto_offered "$proto" yes - if "$wide"; then - for (( i=0 ; i/dev/null $tmpvar - if sclient_connect_successful $? $tmpvar; then - awk '/-----BEGIN/,/-----END/ { print $0 }' $tmpvar >$HOSTCERT - return 0 - else - if [[ -z "$1" ]]; then - prln_warning "could not retrieve host certificate!" - fileout "host_certificate_Problem" "WARN" "Could not retrieve host certificate!" - fi - return 1 - fi - #tmpfile_handle ${FUNCNAME[0]}.txt - #return $((${PIPESTATUS[0]} + ${PIPESTATUS[1]})) -} - -verify_retcode_helper() { - local ret=0 - local -i retcode=$1 - - case $retcode in - # codes from ./doc/apps/verify.pod | verify(1ssl) - 44) tm_out "(different CRL scope)" ;; # X509_V_ERR_DIFFERENT_CRL_SCOPE - 26) tm_out "(unsupported certificate purpose)" ;; # X509_V_ERR_INVALID_PURPOSE - 24) tm_out "(certificate unreadable)" ;; # X509_V_ERR_INVALID_CA - 23) tm_out "(certificate revoked)" ;; # X509_V_ERR_CERT_REVOKED - 21) tm_out "(chain incomplete, only 1 cert provided)" ;; # X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE - 20) tm_out "(chain incomplete)" ;; # X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY - 19) tm_out "(self signed CA in chain)" ;; # X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN - 18) tm_out "(self signed)" ;; # X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT - 10) tm_out "(expired)" ;; # X509_V_ERR_CERT_HAS_EXPIRED - 9) tm_out "(not yet valid)" ;; # X509_V_ERR_CERT_NOT_YET_VALID - 2) tm_out "(issuer cert missing)" ;; # X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT - *) ret=1 ; tm_out " (unknown, pls report) $1" ;; - esac - return $ret -} - -# arg1: number of certificate if provided >1 -determine_trust() { - local jsonID="$1" - local json_postfix="$2" - local -i i=1 - local -i num_ca_bundles=0 - local bundle_fname="" - local -a certificate_file verify_retcode trust - local ok_was="" - local notok_was="" - local all_ok=true - local some_ok=false - local code - local ca_bundles="" - local spaces=" " - local -i certificates_provided=1+$(grep -ce '-----BEGIN CERTIFICATE-----' $TEMPDIR/intermediatecerts.pem) - local addtl_warning - - # If $json_postfix is not empty, then there is more than one certificate - # and the output should should be indented by two more spaces. - [[ -n $json_postfix ]] && spaces=" " - - case $OSSL_VER_MAJOR.$OSSL_VER_MINOR in - 1.0.2|1.1.0|1.1.1|2.[1-9].*|3.*) # 2.x is LibreSSL. 2.1.1 was tested to work, below is not sure - : - ;; - *) addtl_warning="Your $OPENSSL <= 1.0.2 might be too unreliable to determine trust" - fileout "${jsonID}${json_postfix}" "WARN" "$addtl_warning" - addtl_warning="(${addtl_warning})" - ;; - esac - debugme tmln_out - - # if you run testssl.sh from a different path /you can set either TESTSSL_INSTALL_DIR or CA_BUNDLES_PATH to find the CA BUNDLES - if [[ -z "$CA_BUNDLES_PATH" ]]; then - ca_bundles="$TESTSSL_INSTALL_DIR/etc/*.pem" - else - ca_bundles="$CA_BUNDLES_PATH/*.pem" - fi - for bundle_fname in $ca_bundles; do - certificate_file[i]=$(basename ${bundle_fname//.pem}) - if [[ ! -r $bundle_fname ]]; then - prln_warning "\"$bundle_fname\" cannot be found / not readable" - return 1 - fi - debugme printf -- " %-12s" "${certificate_file[i]}" - # Set SSL_CERT_DIR to /dev/null so that $OPENSSL verify will only use certificates in $bundle_fname - # in a subshell because that should be valid here only - (export SSL_CERT_DIR="/dev/null"; export SSL_CERT_FILE="/dev/null" - if [[ $certificates_provided -ge 2 ]]; then - $OPENSSL verify $TRUSTED1ST -purpose sslserver -CAfile <(cat $ADDTL_CA_FILES "$bundle_fname") -untrusted $TEMPDIR/intermediatecerts.pem $HOSTCERT >$TEMPDIR/${certificate_file[i]}.1 2>$TEMPDIR/${certificate_file[i]}.2 - else - $OPENSSL verify $TRUSTED1ST -purpose sslserver -CAfile <(cat $ADDTL_CA_FILES "$bundle_fname") $HOSTCERT >$TEMPDIR/${certificate_file[i]}.1 2>$TEMPDIR/${certificate_file[i]}.2 - fi) - verify_retcode[i]=$(awk '/error [1-9][0-9]? at [0-9]+ depth lookup:/ { if (!found) {print $2; found=1} }' $TEMPDIR/${certificate_file[i]}.1 $TEMPDIR/${certificate_file[i]}.2) - [[ -z "${verify_retcode[i]}" ]] && verify_retcode[i]=0 - if [[ ${verify_retcode[i]} -eq 0 ]]; then - trust[i]=true - some_ok=true - [[ -z "$GOOD_CA_BUNDLE" ]] && GOOD_CA_BUNDLE="$bundle_fname" - debugme tm_svrty_good "Ok " - debugme tmln_out "${verify_retcode[i]}" - else - trust[i]=false - all_ok=false - debugme tm_svrty_high "not trusted " - debugme tmln_out "${verify_retcode[i]}" - fi - ((i++)) - done - num_ca_bundles=$((i - 1)) - debugme tm_out " " - if "$all_ok"; then - # all stores ok - pr_svrty_good "Ok "; pr_warning "$addtl_warning" - # we did to stdout the warning above already, so we could stay here with OK: - fileout "${jsonID}${json_postfix}" "OK" "passed. $addtl_warning" - else - pr_svrty_critical "NOT ok" - if ! "$some_ok"; then - # ALL failed (we assume with the same issue), we're displaying the reason - out " " - code="$(verify_retcode_helper "${verify_retcode[1]}")" - if [[ "$code" =~ "pls report" ]]; then - pr_warning "$code" - else - out "$code" - fi - fileout "${jsonID}${json_postfix}" "CRITICAL" "failed $code. $addtl_warning" - set_grade_cap "T" "Issues with the chain of trust $code" - else - # alt least one ok and other(s) not ==> display the culprit store(s) - if "$some_ok"; then - pr_svrty_critical ":" - for (( i=1; i<=num_ca_bundles; i++ )); do - if ${trust[i]}; then - ok_was="${certificate_file[i]} $ok_was" - else - pr_svrty_high " ${certificate_file[i]} " - code="$(verify_retcode_helper "${verify_retcode[i]}")" - if [[ "$code" =~ "pls report" ]]; then - pr_warning "$code" - else - out "$code" - fi - notok_was="${certificate_file[i]} $code $notok_was" - if ! [[ ${certificate_file[i]} =~ Java ]]; then - # Exemption for Java AND rating, as this store doesn't seem to be as complete. - # We won't penalize this but we still need to raise a red flag. See #1648 - set_grade_cap "T" "Issues with chain of trust $code" - fi - fi - done - outln - # lf + green ones - [[ "$DEBUG" -eq 0 ]] && tm_out "$spaces" - pr_svrty_good "OK: $ok_was" - fi - fileout "${jsonID}${json_postfix}" "CRITICAL" "Some certificate trust checks failed -> $notok_was $addtl_warning, OK -> $ok_was" - fi - [[ -n "$addtl_warning" ]] && out "\n$spaces" && pr_warning "$addtl_warning" - fi - outln - return 0 -} -# not handled: Root CA supplied ("contains anchor" in SSLlabs terminology) - -tls_time() { - local difftime - local spaces=" " - local jsonID="TLS_timestamp" - - pr_bold " TLS clock skew" ; out "$spaces" - - if [[ "$STARTTLS_PROTOCOL" =~ irc ]]; then - prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" - return 1 - fi - - TLS_DIFFTIME_SET=true # this is a switch whether we want to measure the remote TLS_TIME - tls_sockets "01" "$TLS_CIPHER" # try first TLS 1.0 (most frequently used protocol) - [[ -z "$TLS_TIME" ]] && tls_sockets "03" "$TLS12_CIPHER" # TLS 1.2 - [[ -z "$TLS_TIME" ]] && tls_sockets "02" "$TLS_CIPHER" # TLS 1.1 - [[ -z "$TLS_TIME" ]] && tls_sockets "00" "$TLS_CIPHER" # SSL 3 - - if [[ -n "$TLS_TIME" ]]; then # nothing returned a time! - difftime=$((TLS_TIME - TLS_NOW)) # TLS_NOW has been set in tls_sockets() - if [[ "${#difftime}" -gt 5 ]]; then - # openssl >= 1.0.1f fills this field with random values! --> good for possible fingerprint - out "Random values, no fingerprinting possible " - fileout "$jsonID" "INFO" "random" - else - [[ $difftime != "-"* ]] && [[ $difftime != "0" ]] && difftime="+$difftime" - out "$difftime"; out " sec from localtime"; - fileout "$jsonID" "INFO" "off by $difftime seconds from your localtime" - fi - debugme tm_out "$TLS_TIME" - outln - else - outln "SSLv3 through TLS 1.2 didn't return a timestamp" - fileout "$jsonID" "INFO" "None returned by SSLv3 through TLSv1.2" - fi - TLS_DIFFTIME_SET=false # reset the switch to save calls to date and friend in tls_sockets() - return 0 -} - -# core function determining whether handshake succeeded or not -# arg1: return value of "openssl s_client connect" -# arg2: temporary file with the server hello -# returns 0 if connect was successful, 1 if not -# -sclient_connect_successful() { - local server_hello="$(cat -v "$2")" - local connect_success=false - local re='Master-Key: ([^\ -]*)' - - [[ $1 -eq 0 ]] && connect_success=true - if ! "$connect_success" && [[ "$server_hello" =~ $re ]]; then - [[ -n "${BASH_REMATCH[1]}" ]] && connect_success=true - fi - ! "$connect_success" && [[ "$server_hello" =~ (New|Reused)", "(SSLv[23]|TLSv1(\.[0-3])?(\/SSLv3)?)", Cipher is "([A-Z0-9]+-[A-Za-z0-9\-]+|TLS_[A-Za-z0-9_]+) ]] && connect_success=true - if "$connect_success"; then - "$NO_SSL_SESSIONID" && [[ "$server_hello" =~ Session-ID:\ [a-fA-F0-9]{2,64} ]] && NO_SSL_SESSIONID=false - return 0 - fi - # what's left now is: master key empty and Session-ID not empty - # ==> probably client-based auth with x509 certificate. We handle that at other places - # - # For robustness we also detected here network / server connectivity problems: - # Just need to check whether $TMPFILE=$2 is empty - if [[ ! -s "$2" ]]; then - ((NR_OSSL_FAIL++)) - connectivity_problem $NR_OSSL_FAIL $MAX_OSSL_FAIL "openssl s_client connect problem" "repeated openssl s_client connect problem, doesn't make sense to continue" - fi - return 1 -} - -extract_new_tls_extensions() { - local tls_extensions - - # this is not beautiful (grep+sed) - # but maybe we should just get the ids and do a private matching, according to - # https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml - tls_extensions=$(grep -a 'TLS server extension ' "$1" | \ - sed -e 's/TLS server extension //g' -e 's/\" (id=/\/#/g' \ - -e 's/,.*$/,/g' -e 's/),$/\"/g' \ - -e 's/elliptic curves\/#10/supported_groups\/#10/g') - tls_extensions=$(echo $tls_extensions) # into one line - - if [[ -n "$tls_extensions" ]]; then - # check to see if any new TLS extensions were returned and add any new ones to TLS_EXTENSIONS - while read -d "\"" -r line; do - if [[ $line != "" ]] && [[ ! "$TLS_EXTENSIONS" =~ "$line" ]]; then -#FIXME: This is a string of quoted strings, so this seems to determine the output format already. Better e.g. would be an array - TLS_EXTENSIONS+=" \"${line}\"" - fi - done <<<$tls_extensions - [[ "${TLS_EXTENSIONS:0:1}" == " " ]] && TLS_EXTENSIONS="${TLS_EXTENSIONS:1}" - fi -} - -# Note that since, at the moment, this function is only called by run_server_defaults() -# and run_heartbleed(), this function does not look for the status request or NPN -# extensions. For run_heartbleed(), only the heartbeat extension needs to be detected. -# For run_server_defaults(), the status request and NPN would already be detected by -# get_server_certificate(), if they are supported. In the case of the status extension, -# since including a status request extension in a ClientHello does not work for GOST -# only servers. In the case of NPN, since a server will not include both the NPN and -# ALPN extensions in the same ServerHello. -# -determine_tls_extensions() { - local addcmd - local -i success=1 - local line params="" tls_extensions="" - local alpn_proto alpn="" alpn_list_len_hex alpn_extn_len_hex - local -i alpn_list_len alpn_extn_len - local cbc_cipher_list="ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CAMELLIA256-SHA384:DHE-RSA-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA256:DH-RSA-CAMELLIA256-SHA256:DH-DSS-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-CAMELLIA256-SHA384:ECDH-ECDSA-CAMELLIA256-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA256:DH-RSA-CAMELLIA128-SHA256:DH-DSS-CAMELLIA128-SHA256:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-CAMELLIA128-SHA256:ECDH-ECDSA-CAMELLIA128-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" - local cbc_cipher_list_hex="c0,28, c0,24, c0,14, c0,0a, 00,6b, 00,6a, 00,69, 00,68, 00,39, 00,38, 00,37, 00,36, c0,77, c0,73, 00,c4, 00,c3, 00,c2, 00,c1, 00,88, 00,87, 00,86, 00,85, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, 00,3d, 00,35, 00,c0, 00,84, c0,3d, c0,3f, c0,41, c0,43, c0,45, c0,49, c0,4b, c0,4d, c0,4f, c0,27, c0,23, c0,13, c0,09, 00,67, 00,40, 00,3f, 00,3e, 00,33, 00,32, 00,31, 00,30, c0,76, c0,72, 00,be, 00,bd, 00,bc, 00,bb, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, 00,3c, 00,2f, 00,ba, 00,96, 00,41, 00,07, c0,3c, c0,3e, c0,40, c0,42, c0,44, c0,48, c0,4a, c0,4c, c0,4e, c0,12, c0,08, 00,16, 00,13, 00,10, 00,0d, c0,0d, c0,03, 00,0a, fe,ff, ff,e0, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,62, 00,09, fe,fe, ff,e1, 00,14, 00,11, 00,08, 00,06, 00,0b, 00,0e" - local using_sockets=true - - [[ "$OPTIMAL_PROTO" == -ssl2 ]] && return 0 - "$SSL_NATIVE" && using_sockets=false - - if "$using_sockets"; then - tls_extensions="00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00" - if [[ -z $STARTTLS ]]; then - for alpn_proto in $ALPN_PROTOs; do - alpn+=",$(printf "%02x" ${#alpn_proto}),$(string_to_asciihex "$alpn_proto")" - done - alpn_list_len=${#alpn}/3 - alpn_list_len_hex=$(printf "%04x" $alpn_list_len) - alpn_extn_len=$alpn_list_len+2 - alpn_extn_len_hex=$(printf "%04x" $alpn_extn_len) - tls_extensions+=", 00,10,${alpn_extn_len_hex:0:2},${alpn_extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn" - fi - if [[ ! "$TLS_EXTENSIONS" =~ encrypt-then-mac ]]; then - tls_sockets "03" "$cbc_cipher_list_hex, 00,ff" "all" "$tls_extensions" - success=$? - fi - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - tls_sockets "03" "$TLS12_CIPHER" "all" "$tls_extensions" - success=$? - fi - [[ $success -eq 2 ]] && success=0 - [[ $success -eq 0 ]] && extract_new_tls_extensions "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" - if [[ -r "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ]]; then - cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE - tmpfile_handle ${FUNCNAME[0]}.txt - fi - else - if "$HAS_ALPN" && [[ -z $STARTTLS ]]; then - params="-alpn \"${ALPN_PROTOs// /,}\"" # we need to replace " " by "," - elif "$HAS_NPN" && [[ -z $STARTTLS ]]; then - params="-nextprotoneg \"$NPN_PROTOs\"" - fi - if [[ -z "$OPTIMAL_PROTO" ]] && [[ -z "$SNI" ]] && "$HAS_NO_SSL2"; then - addcmd="-no_ssl2" - else - addcmd="$SNI" - fi - if [[ ! "$TLS_EXTENSIONS" =~ encrypt-then-mac ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params -cipher $cbc_cipher_list") $ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE - success=$? - fi - if [[ $success -ne 0 ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params") $ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE - success=$? - fi - [[ $success -eq 0 ]] && extract_new_tls_extensions $TMPFILE - tmpfile_handle ${FUNCNAME[0]}.txt - fi - - # Keep it "on file" for debugging purposes - [[ "$DEBUG" -ge 1 ]] && safe_echo "$TLS_EXTENSIONS" >"$TEMPDIR/$NODE.$NODEIP.tls_extensions.txt" - - return $success -} - -# Return a list of the certificate compression methods supported (RFC 8879) -determine_cert_compression() { - # 1=zlib, 2=brotli, 3=zstd - local -a supported_compression_methods=("" "false" "false" "false") - local -i i len nr_compression_methods=3 - local len1 len2 methods_to_test method_found method_nr methods_found="" - - # Certificate compression is only supported by TLS 1.3. - [[ $(has_server_protocol "tls1_3") -eq 1 ]] && return 1 - while true; do - methods_to_test="" - for (( i=1; i <= nr_compression_methods; i++ )); do - ! "${supported_compression_methods[i]}" && methods_to_test+=" ,00,$(printf "%02x" $i)" - done - len=$((2*${#methods_to_test}/7)) - # If there are no more compression methods remaining to be tested, then quit. - [[ $len -eq 0 ]] && break - len1=$(printf "%02x" "$len") - len2=$(printf "%02x" "$((len+1))") - tls_sockets "04" "$TLS13_CIPHER" "all+" "00,1b, 00,$len2, $len1$methods_to_test" - if [[ $? -ne 0 ]]; then - add_proto_offered tls1_3 no - return 1 - fi - add_proto_offered tls1_3 yes - method_found="$(awk '/Certificate Compression Algorithm: / { print $4 $5 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - [[ -z "$method_found" ]] && break - [[ -z "$methods_found" ]] && tmpfile_handle ${FUNCNAME[0]}.txt "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" - method_found="${method_found//(//}" - method_found="${method_found//)/}" - method_nr="${method_found%%/*}" - supported_compression_methods[method_nr]=true - methods_found+=" $method_found" - done - if [[ -n "$methods_found" ]]; then - TLS13_CERT_COMPRESS_METHODS="${methods_found:1}" - else - TLS13_CERT_COMPRESS_METHODS="none" - fi - return 0 -} - -extract_certificates() { - local version="$1" - local savedir - local -i i success nrsaved=0 - local issuerDN CAsubjectDN previssuerDN - - # Place the server's certificate in $HOSTCERT and any intermediate - # certificates that were provided in $TEMPDIR/intermediatecerts.pem - savedir="$PWD"; cd $TEMPDIR - # https://backreference.org/2010/05/09/ocsp-verification-with-openssl/ - if [[ "$version" == ssl2 ]]; then - awk -v n=-1 '/Server certificate/ {start=1} - /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } - inc { print > ("level" n ".crt") } - /---END CERTIFICATE-----/{ inc=0 }' $TMPFILE - else - awk -v n=-1 '/Certificate chain/ {start=1} - /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } - inc { print > ("level" n ".crt") } - /---END CERTIFICATE-----/{ inc=0 }' $TMPFILE - fi - [[ -s level0.crt ]] && nrsaved=$(count_words "$(echo level?.crt 2>/dev/null)") - if [[ $nrsaved -eq 0 ]]; then - success=1 - else - success=0 - CERTIFICATE_LIST_ORDERING_PROBLEM=false - mv level0.crt $HOSTCERT - if [[ $nrsaved -eq 1 ]]; then - echo "" > $TEMPDIR/intermediatecerts.pem - else - cat level?.crt > $TEMPDIR/intermediatecerts.pem - issuerDN="$($OPENSSL x509 -in $HOSTCERT -noout -issuer 2>/dev/null)" - issuerDN="${issuerDN:8}" - previssuerDN="$issuerDN" - # The second certificate (level1.crt) SHOULD be issued to the CA - # that issued the server's certificate. But, according to RFC 8446 - # clients SHOULD be prepared to handle cases in which the server - # does not order the certificates correctly. - for (( i=1; i < nrsaved; i++ )); do - CAsubjectDN="$($OPENSSL x509 -in "level$i.crt" -noout -subject 2>/dev/null)" - if [[ "${CAsubjectDN:9}" == "$issuerDN" ]]; then - cp "level$i.crt" $TEMPDIR/hostcert_issuer.pem - issuerDN="" # set to empty to prevent further matches - fi - [[ "${CAsubjectDN:9}" != "$previssuerDN" ]] && CERTIFICATE_LIST_ORDERING_PROBLEM=true - "$CERTIFICATE_LIST_ORDERING_PROBLEM" && [[ -z "$issuerDN" ]] && break - previssuerDN="$($OPENSSL x509 -in "level$i.crt" -noout -issuer 2>/dev/null)" - previssuerDN="${previssuerDN:8}" - done - # This should never happen, but if more than one certificate was - # provided and none of them belong to the CA that issued the - # server's certificate, then the extra certificates should just - # be deleted. There is code elsewhere that assumes that if - # $TEMPDIR/intermediatecerts.pem is non-empty, then - # $TEMPDIR/hostcert_issuer.pem is also present. - [[ -n "$issuerDN" ]] && echo "" > $TEMPDIR/intermediatecerts.pem - rm level?.crt - fi - fi - cd "$savedir" - return $success -} - -extract_stapled_ocsp() { - local response="$(cat $TMPFILE)" - local ocsp tmp - local -i ocsp_len - - STAPLED_OCSP_RESPONSE="" - if [[ "$response" =~ CertificateStatus ]]; then - # This is OpenSSL 1.1.0 or 1.1.1 and the response - # is TLS 1.2 or earlier. - ocsp="${response##*CertificateStatus}" - ocsp="16${ocsp#*16}" - ocsp="${ocsp%%<<<*}" - ocsp="$(strip_spaces "$(newline_to_spaces "$ocsp")")" - ocsp="${ocsp:8}" - elif [[ "$response" =~ TLS\ server\ extension\ \"status\ request\"\ \(id=5\)\,\ len=0 ]]; then - # This is not OpenSSL 1.1.0 or 1.1.1, and the response - # is TLS 1.2 or earlier. - ocsp="${response%%OCSP response:*}" - ocsp="${ocsp##*<<<}" - ocsp="16${ocsp#*16}" - ocsp="$(strip_spaces "$(newline_to_spaces "$ocsp")")" - ocsp="${ocsp:8}" - elif [[ "$response" =~ TLS\ server\ extension\ \"status\ request\"\ \(id=5\)\,\ len= ]]; then - # This is OpenSSL 1.1.1 and the response is TLS 1.3. - ocsp="${response##*TLS server extension \"status request\" (id=5), len=}" - ocsp="${ocsp%%<<<*}" - tmp="${ocsp%%[!0-9]*}" - ocsp="${ocsp#$tmp}" - ocsp_len=2*$tmp - ocsp="$(awk ' { print $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 } ' <<< "$ocsp" | sed 's/-//')" - ocsp="$(strip_spaces "$(newline_to_spaces "$ocsp")")" - ocsp="${ocsp:0:ocsp_len}" - else - return 0 - fi - # Determine whether this is a single OCSP response or a sequence of - # responses and then extract just the response for the server's - # certificate. - if [[ "${ocsp:0:2}" == "01" ]]; then - STAPLED_OCSP_RESPONSE="${ocsp:8}" - elif [[ "${ocsp:0:2}" == "02" ]]; then - ocsp_len=2*$(hex2dec "${tls_certificate_status_ascii:8:6}") - STAPLED_OCSP_RESPONSE="${ocsp:14:ocsp_len}" - fi - return 0 -} - -# arg1 is "" -# arg2 is a list of protocols to try (tls1_2, tls1_1, tls1, ssl3) or empty (if all should be tried) -get_server_certificate() { - local protocols_to_try proto - local success ret - local npn_params="" line - local ciphers_to_test="" - # Cipher suites that use a certificate with an RSA (signature) public key - local -r a_rsa="cc,13, cc,15, c0,30, c0,28, c0,14, 00,9f, cc,a8, cc,aa, c0,a3, c0,9f, 00,6b, 00,39, c0,77, 00,c4, 00,88, c0,45, c0,4d, c0,53, c0,61, c0,7d, c0,8b, 16,b7, 16,b9, c0,2f, c0,27, c0,13, 00,9e, c0,a2, c0,9e, 00,67, 00,33, c0,76, 00,be, 00,9a, 00,45, c0,44, c0,4c, c0,52, c0,60, c0,7c, c0,8a, c0,11, c0,12, 00,16, 00,15, 00,14, c0,10" - # Cipher suites that use a certificate with an RSA (encryption) public key - local -r e_rsa="00,b7, c0,99, 00,ad, cc,ae, 00,9d, c0,a1, c0,9d, 00,3d, 00,35, 00,c0, 00,84, 00,95, c0,3d, c0,51, c0,69, c0,6f, c0,7b, c0,93, ff,01, 00,ac, c0,a0, c0,9c, 00,9c, 00,3c, 00,2f, 00,ba, 00,b6, 00,96, 00,41, c0,98, 00,07, 00,94, c0,3c, c0,50, c0,68, c0,6e, c0,7a, c0,92, 00,05, 00,04, 00,92, 00,0a, 00,93, fe,ff, ff,e0, 00,62, 00,09, 00,61, fe,fe, ff,e1, 00,64, 00,60, 00,08, 00,06, 00,03, 00,b9, 00,b8, 00,2e, 00,3b, 00,02, 00,01, ff,00" - # Cipher suites that use a certificate with a DSA public key - local -r a_dss="00,a3, 00,6a, 00,38, 00,c3, 00,87, c0,43, c0,57, c0,81, 00,a2, 00,40, 00,32, 00,bd, 00,99, 00,44, c0,42, c0,56, c0,80, 00,66, 00,13, 00,63, 00,12, 00,65, 00,11" - # Cipher suites that use a certificate with a DH public key - local -r a_dh="00,a5, 00,a1, 00,69, 00,68, 00,37, 00,36, 00,c2, 00,c1, 00,86, 00,85, c0,3f, c0,41, c0,55, c0,59, c0,7f, c0,83, 00,a4, 00,a0, 00,3f, 00,3e, 00,31, 00,30, 00,bc, 00,bb, 00,98, 00,97, 00,43, 00,42, c0,3e, c0,40, c0,54, c0,58, c0,7e, c0,82, 00,10, 00,0d, 00,0f, 00,0c, 00,0b, 00,0e" - # Cipher suites that use a certificate with an ECDH public key - local -r a_ecdh="c0,32, c0,2e, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, c0,4b, c0,4f, c0,5f, c0,63, c0,89, c0,8d, c0,31, c0,2d, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, c0,4a, c0,4e, c0,5e, c0,62, c0,88, c0,8c, c0,0c, c0,02, c0,0d, c0,03, c0,0b, c0,01" - # Cipher suites that use a certificate with an ECDSA public key - local -r a_ecdsa="cc,14, c0,2c, c0,24, c0,0a, cc,a9, c0,af, c0,ad, c0,73, c0,49, c0,5d, c0,87, 16,b8, 16,ba, c0,2b, c0,23, c0,09, c0,ae, c0,ac, c0,72, c0,48, c0,5c, c0,86, c0,07, c0,08, c0,06" - # Cipher suites that use a certificate with a GOST public key - local -r a_gost="00,80, 00,81, 00,82, 00,83" - local using_sockets=true - - "$SSL_NATIVE" && using_sockets=false - - CERTIFICATE_LIST_ORDERING_PROBLEM=false - if [[ "$1" =~ tls1_3 ]]; then - [[ $(has_server_protocol "tls1_3") -eq 1 ]] && return 1 - if "$HAS_TLS13" && "$HAS_SIGALGS" && [[ ! "$1" =~ tls1_3_EdDSA ]]; then - if [[ "$1" =~ tls1_3_RSA ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -showcerts -connect $NODEIP:$PORT $PROXY $SNI -tls1_3 -tlsextdebug -status -msg -sigalgs PSS+SHA256:PSS+SHA384:PSS+SHA512:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512") $ERRFILE >$TMPFILE - elif [[ "$1" =~ tls1_3_ECDSA ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -showcerts -connect $NODEIP:$PORT $PROXY $SNI -tls1_3 -tlsextdebug -status -msg -sigalgs ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512") $ERRFILE >$TMPFILE - else - return 1 - fi - sclient_connect_successful $? $TMPFILE || return 1 - DETECTED_TLS_VERSION="0304" - extract_certificates "tls1_3" - extract_stapled_ocsp - success=$? - else - # For STARTTLS protocols not being implemented yet via sockets this is a bypass otherwise it won't be usable at all (e.g. LDAP) - if [[ "$STARTTLS" =~ irc ]]; then - return 1 - elif [[ "$1" =~ tls1_3_RSA ]]; then - tls_sockets "04" "$TLS13_CIPHER" "all+" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,16,00,14,08,04,08,05,08,06,04,01,05,01,06,01,02,01,08,09,08,0a,08,0b" - elif [[ "$1" =~ tls1_3_ECDSA ]]; then - tls_sockets "04" "$TLS13_CIPHER" "all+" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,0a,00,08,04,03,05,03,06,03,02,03" - elif [[ "$1" =~ tls1_3_EdDSA ]]; then - tls_sockets "04" "$TLS13_CIPHER" "all+" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,06,00,04,08,07,08,08" - else - return 1 - fi - success=$? - [[ $success -eq 0 ]] || return 1 - cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE - fi - [[ $success -eq 0 ]] && add_proto_offered tls1_3 yes - extract_new_tls_extensions $TMPFILE - tmpfile_handle ${FUNCNAME[0]}.txt - return $success - fi - - "$HAS_NPN" && [[ -z "$STARTTLS" ]] && npn_params="-nextprotoneg \"$NPN_PROTOs\"" - - if [[ -n "$2" ]]; then - protocols_to_try="$2" - else - protocols_to_try="tls1_2 tls1_1 tls1 ssl3" - fi - - # throwing 1st every cipher/protocol at the server to know what works - success=7 - - if [[ "$OPTIMAL_PROTO" == -ssl2 ]]; then - success=1 - sslv2_sockets "" "true" - if [[ $? -eq 3 ]]; then - mv $TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt $TMPFILE - success=0 - fi - tmpfile_handle ${FUNCNAME[0]}.txt - return $success - fi - - if "$using_sockets"; then - protocols_to_try="${protocols_to_try/tls1_2/03}" - protocols_to_try="${protocols_to_try/tls1_1/02}" - protocols_to_try="${protocols_to_try/tls1/01}" - protocols_to_try="${protocols_to_try/ssl3/00}" - - [[ "$1" =~ aRSA ]] && ciphers_to_test+=", $a_rsa" - [[ "$1" =~ eRSA ]] && ciphers_to_test+=", $e_rsa" - [[ "$1" =~ aDSS ]] && ciphers_to_test+=", $a_dss" - [[ "$1" =~ aDH ]] && ciphers_to_test+=", $a_dh" - [[ "$1" =~ aECDH ]] && ciphers_to_test+=", $a_ecdh" - [[ "$1" =~ aECDSA ]] && ciphers_to_test+=", $a_ecdsa" - [[ "$1" =~ aGOST ]] && ciphers_to_test+=", $a_gost" - - [[ -z "$ciphers_to_test" ]] && return 1 - ciphers_to_test="${ciphers_to_test:2}" - - for proto in $protocols_to_try; do - [[ 1 -eq $(has_server_protocol $proto) ]] && continue - tls_sockets "$proto" "$ciphers_to_test, 00,ff" "all" "00,12,00,00, 00,05,00,05,01,00,00,00,00" - ret=$? - [[ $ret -eq 0 ]] && success=0 && break - [[ $ret -eq 2 ]] && success=0 && break - done # this loop is needed for IIS6 and others which have a handshake size limitations - if [[ $success -eq 7 ]]; then - # "-status" above doesn't work for GOST only servers, so we do another test without it and see whether that works then: - tls_sockets "$proto" "$ciphers_to_test, 00,ff" "all" "00,12,00,00" - ret=$? - [[ $ret -eq 0 ]] && success=0 - [[ $ret -eq 2 ]] && success=0 - if [[ $success -eq 7 ]]; then - if [ -z "$1" ]; then - prln_warning "Strange, no SSL/TLS protocol seems to be supported (error around line $((LINENO - 6)))" - fi - tmpfile_handle ${FUNCNAME[0]}.txt - return 7 # this is ugly, I know - else - GOST_STATUS_PROBLEM=true - fi - fi - cp $TEMPDIR/$NODEIP.parse_tls_serverhello.txt $TMPFILE - - # When "$2" is empty, get_server_certificate() is being called with SNI="". - # In case the extensions returned by the server differ depending on whether - # SNI is provided or not, don't collect extensions when SNI="" (unless - # no DNS name was provided at the command line). - [[ -z "$2" ]] && extract_new_tls_extensions $TMPFILE - else - # no sockets, openssl - ciphers_to_test="$1" - if [[ "$1" =~ aRSA ]] && [[ "$1" =~ eRSA ]]; then - ciphers_to_test="${ciphers_to_test/eRSA/}" - elif [[ "$1" =~ aRSA ]]; then - ciphers_to_test="${ciphers_to_test/aRSA/}" - for ciph in $(colon_to_spaces $(actually_supported_osslciphers "aRSA")); do - [[ "$ciph" =~ -RSA- ]] && ciphers_to_test+=":$ciph" - done - elif [[ "$1" =~ eRSA ]]; then - ciphers_to_test="${ciphers_to_test/eRSA/}" - for ciph in $(colon_to_spaces $(actually_supported_osslciphers "aRSA")); do - [[ ! "$ciph" =~ -RSA- ]] && ciphers_to_test+=":$ciph" - done - fi - ciphers_to_test="${ciphers_to_test/::/:}" - [[ "${ciphers_to_test:0:1}" == : ]] && ciphers_to_test="${ciphers_to_test:1}" - [[ $(count_ciphers $(actually_supported_osslciphers "$ciphers_to_test")) -ge 1 ]] || return 1 - - for proto in $protocols_to_try; do - [[ 1 -eq $(has_server_protocol $proto) ]] && continue - [[ "$proto" == ssl3 ]] && ! "$HAS_SSL3" && continue - addcmd="" - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -cipher $ciphers_to_test -showcerts -connect $NODEIP:$PORT $PROXY $SNI -$proto -tlsextdebug $npn_params -status -msg") $ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE; then - success=0 - break # now we have the certificate - fi - done # this loop is needed for IIS6 and others which have a handshake size limitations - if [[ $success -eq 7 ]]; then - # "-status" above doesn't work for GOST only servers, so we do another test without it and see whether that works then: - [[ "$proto" == ssl3 ]] && ! "$HAS_SSL3" && return 7 - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -cipher $ciphers_to_test -showcerts -connect $NODEIP:$PORT $PROXY $SNI -$proto -tlsextdebug") >$ERRFILE >$TMPFILE - if ! sclient_connect_successful $? $TMPFILE; then - if [ -z "$1" ]; then - prln_warning "Strange, no SSL/TLS protocol seems to be supported (error around line $((LINENO - 6)))" - fi - tmpfile_handle ${FUNCNAME[0]}.txt - return 7 # this is ugly, I know - else - GOST_STATUS_PROBLEM=true - fi - fi - case "$proto" in - "tls1_2") DETECTED_TLS_VERSION="0303" ;; - "tls1_1") DETECTED_TLS_VERSION="0302" ;; - "tls1") DETECTED_TLS_VERSION="0301" ;; - "ssl3") DETECTED_TLS_VERSION="0300" ;; - esac - # When "$2" is empty, get_server_certificate() is being called with SNI="". - # In case the extensions returned by the server differ depending on whether - # SNI is provided or not, don't collect extensions when SNI="" (unless - # no DNS name was provided at the command line). - [[ -z "$2" ]] && extract_new_tls_extensions $TMPFILE - - extract_certificates "$proto" - extract_stapled_ocsp - success=$? - fi - tmpfile_handle ${FUNCNAME[0]}.txt - return $success -} - -# arg1: path to certificate -# returns CN -get_cn_from_cert() { - local subject - - # attention! openssl 1.0.2 doesn't properly handle online output from certificates from trustwave.com/github.com - #FIXME: use -nameopt oid for robustness - - # for e.g. russian sites -esc_msb,utf8 works in an UTF8 terminal -- any way to check platform independent? - # see x509(1ssl): - subject="$($OPENSSL x509 -in $1 -noout -subject -nameopt multiline,-align,sname,-esc_msb,utf8,-space_eq 2>>$ERRFILE)" - echo "$(awk -F'=' '/CN=/ { print $2 }' <<< "$subject" | tr '\n' ' ')" - return $? -} - -# Return 0 if the name provided in arg1 is a wildcard name -is_wildcard() -{ - local certname="$1" - - # If the first label in the DNS name begins "xn--", then assume it is an - # A-label and not a wildcard name (RFC 6125, Section 6.4.3). - [[ "${certname:0:4}" == "xn--" ]] && return 1 - - # Remove part of name preceding '*' or '.'. If no "*" appears in the - # left-most label, then it is not a wildcard name (RFC 6125, Section 6.4.3). - basename="$(echo -n "$certname" | sed 's/^[_a-zA-Z0-9\-]*//')" - [[ "${basename:0:1}" != "*" ]] && return 1 # not a wildcard name - - # Check that there are no additional wildcard ('*') characters or any - # other characters that do not belong in a DNS name. - [[ -n $(echo -n "${basename:1}" | sed 's/^[_\.a-zA-Z0-9\-]*//') ]] && return 1 - return 0 -} - -# Return 0 if the name provided in arg2 is a wildcard name and it matches the name provided in arg1. -wildcard_match() -{ - local servername="$1" - local certname="$2" - local basename - local -i basename_offset len_certname len_part1 len_basename - local -i len_servername len_wildcard - - len_servername=${#servername} - len_certname=${#certname} - - # Use rules from RFC 6125 to perform the match. - - # Assume the "*" in the wildcard needs to be replaced by one or more - # characters, although RFC 6125 is not clear about that. - [[ $len_servername -lt $len_certname ]] && return 1 - - is_wildcard "$certname" - [[ $? -ne 0 ]] && return 1 - - # Comparisons of DNS names are case insensitive, so convert both names to uppercase. - certname="$(toupper "$certname")" - servername="$(toupper "$servername")" - - # Extract part of name that comes after the "*" - basename="$(echo -n "$certname" | sed 's/^[_A-Z0-9\-]*\*//')" - len_basename=${#basename} - len_part1=$len_certname-$len_basename-1 - len_wildcard=$len_servername-$len_certname+1 - basename_offset=$len_servername-$len_basename - - # Check that initial part of $servername matches initial part of $certname - # and that final part of $servername matches final part of $certname. - [[ "${servername:0:len_part1}" != "${certname:0:len_part1}" ]] && return 1 - [[ "${servername:basename_offset:len_basename}" != "$basename" ]] && return 1 - - # Check that part of $servername that matches "*" is all part of a single - # domain label. - [[ -n $(echo -n "${servername:len_part1:len_wildcard}" | sed 's/^[_A-Z0-9\-]*//') ]] && return 1 - - return 0 -} - -# Compare the server name provided in arg1 to the CN and SAN in arg2 and return: -# 0, if server name provided does not match any of the names in the CN or SAN -# 1, if the server name provided matches a name in the SAN -# 2, if the server name provided is a wildcard match against a name in the SAN -# 4, if the server name provided matches the CN -# 5, if the server name provided matches the CN AND a name in the SAN -# 6, if the server name provided matches the CN AND is a wildcard match against a name in the SAN -# 8, if the server name provided is a wildcard match against the CN -# 9, if the server name provided matches a name in the SAN AND is a wildcard match against the CN -# 10, if the server name provided is a wildcard match against the CN AND a name in the SAN - -compare_server_name_to_cert() { - local cert="$1" - local servername cns cn dns_sans ip_sans san dercert tag - local srv_id="" xmppaddr="" - local -i i len len1 cn_match=0 - local -i subret=0 # no error condition, passing results - - HAS_DNS_SANS=false - if [[ -n "$XMPP_HOST" ]]; then - # RFC 6120, Section 13.7.2.1, states that for XMPP the identity that - # should appear in the server's certificate is identity that appears - # in the the 'to' address that the client communicates in the initial - # stream header. - servername="$(toupper "$XMPP_HOST")" - else - servername="$(toupper "$NODE")" - fi - - # Check whether any of the DNS names in the certificate match the servername - dns_sans="$(get_san_dns_from_cert "$cert")" - while read san; do - if [[ -n "$san" ]]; then - HAS_DNS_SANS=true - [[ $(toupper "$san") == "$servername" ]] && subret=1 && break - fi - done <<< "$dns_sans" - - if [[ $subret -eq 0 ]]; then - # Check whether any of the IP addresses in the certificate match the servername - ip_sans=$($OPENSSL x509 -in "$cert" -noout -text 2>>$ERRFILE | grep -A2 "Subject Alternative Name" | \ - tr ',' '\n' | grep "IP Address:" | sed -e 's/IP Address://g' -e 's/ //g') - while read san; do - [[ -n "$san" ]] && [[ "$san" == "$servername" ]] && subret=1 && break - done <<< "$ip_sans" - fi - - if [[ $subret -eq 0 ]] && [[ -n "$XMPP_HOST" ]]; then - # For XMPP hosts, in addition to checking for a matching DNS name, - # should also check for a matching SRV-ID or XmppAddr identifier. - dercert="$($OPENSSL x509 -in "$cert" -outform DER 2>>$ERRFILE | hexdump -v -e '16/1 "%02X"')" - # Look for the beginning of the subjectAltName extension. It - # will begin with the OID (2.5.29.17 = 0603551D11). After the OID - # there may be an indication that the extension is critical (0101FF). - # Finally will be the tag indicating that the value of the extension is - # encoded as an OCTET STRING (04). - if [[ "$dercert" =~ 0603551D110101FF04 ]]; then - dercert="${dercert##*0603551D110101FF04}" - else - dercert="${dercert##*0603551D1104}" - fi - # Skip over the encoding of the length of the OCTET STRING. - if [[ "${dercert:0:1}" == "8" ]]; then - i="${dercert:1:1}" - i=2*$i+2 - dercert="${dercert:i}" - else - dercert="${dercert:2}" - fi - # Next byte should be a 30 (SEQUENCE). - if [[ "${dercert:0:2}" == "30" ]]; then - # Get the length of the subjectAltName extension and then skip - # over the encoding of the length. - if [[ "${dercert:2:1}" == "8" ]]; then - case "${dercert:3:1}" in - 1) len=2*0x${dercert:4:2}; dercert="${dercert:6}" ;; - 2) len=2*0x${dercert:4:4}; dercert="${dercert:8}" ;; - 3) len=2*0x${dercert:4:6}; dercert="${dercert:10}" ;; - *) len=0 ;; - esac - else - len=2*0x${dercert:2:2} - dercert="${dercert:4}" - fi - if [[ $len -ne 0 ]] && [[ $len -lt ${#dercert} ]]; then - # loop through all the names and extract the SRV-ID and XmppAddr identifiers - for (( i=0; i < len; i+=len_name )); do - tag="${dercert:i:2}" - i+=2 - if [[ "${dercert:i:1}" == "8" ]]; then - i+=1 - case "${dercert:i:1}" in - 1) i+=1; len_name=2*0x${dercert:i:2}; i+=2 ;; - 2) i+=1; len_name=2*0x${dercert:i:4}; i+=4 ;; - 3) i+=1; len_name=2*0x${dercert:i:6}; i+=4 ;; - *) len=0 ;; - esac - else - len_name=2*0x${dercert:i:2} - i+=2 - fi - if [[ "$tag" == "A0" ]]; then - # This is an otherName. - if [[ $len_name -gt 18 ]] && [[ "${dercert:i:20}" == "06082B06010505070805" || \ - "${dercert:i:20}" == "06082B06010505070807" ]]; then - # According to the OID, this is either an SRV-ID or XmppAddr. - j=$i+20 - if [[ "${dercert:j:2}" == "A0" ]]; then - j+=2 - if [[ "${dercert:j:1}" == "8" ]]; then - j+=1 - j+=2*0x${dercert:j:1}+1 - else - j+=2 - fi - if [[ "${dercert:i:20}" == "06082B06010505070805" && "${dercert:j:2}" == "0C" ]] || \ - [[ "${dercert:i:20}" == "06082B06010505070807" && "${dercert:j:2}" == "16" ]]; then - # XmppAddr should be encoded as UTF8STRING (0C) and - # SRV-ID should be encoded IA5STRING (16). - j+=2 - if [[ "${dercert:j:1}" == "8" ]]; then - j+=1 - case "${dercert:j:1}" in - 1) j+=1; len1=2*0x${dercert:j:2}; j+=2 ;; - 2) j+=1; len1=2*0x${dercert:j:4}; j+=4 ;; - 3) j+=1; len1=2*0x${dercert:j:6}; j+=6 ;; - 4) len1=0 ;; - esac - else - len1=2*0x${dercert:j:2} - j+=2 - fi - if [[ $len1 -ne 0 ]]; then - san="$(hex2binary "${dercert:j:len1}")" - if [[ "${dercert:i:20}" == "06082B06010505070805" ]]; then - xmppaddr+="$san " - else - srv_id+="$san " - fi - fi - fi - fi - fi - fi - done - fi - fi - [[ -n "$srv_id" ]] && HAS_DNS_SANS=true - [[ -n "$xmppaddr" ]] && HAS_DNS_SANS=true - while read -d " " san; do - [[ -n "$san" ]] && [[ $(toupper "$san") == "_XMPP-SERVER.$servername" ]] && subret=1 && break - done <<< "$srv_id" - if [[ $subret -eq 0 ]]; then - while read -d " " san; do - [[ -n "$san" ]] && [[ $(toupper "$san") == "$servername" ]] && subret=1 && break - done <<< "$xmppaddr" - fi - fi - - # Check whether any of the DNS names in the certificate are wildcard names - # that match the servername - if [[ $subret -eq 0 ]]; then - while read san; do - [[ -n "$san" ]] || continue - wildcard_match "$servername" "$san" - [[ $? -eq 0 ]] && subret=2 && break - done <<< "$dns_sans" - fi - - # Get every CN from the subject field and compare against the server name. - cns="$($OPENSSL x509 -in $1 -noout -subject -nameopt multiline,-align,sname,-esc_msb,utf8,-space_eq 2>>$ERRFILE | awk -F'=' '/CN=/ { print $2 }')" - while read cn; do - # If the CN contains any characters that are not valid for a DNS name, - # then assume it does not contain a DNS name. - [[ -n "${cn//[_\.a-zA-Z0-9*\-]/}" ]] && continue - - # Check whether the CN matches the servername - [[ $(toupper "$cn") == "$servername" ]] && cn_match=4 && break - - # Check whether the CN is a wildcard name that matches the servername - # NOTE: Don't stop loop on a wildcard match in case there is another CN - # that is an exact match. - wildcard_match "$servername" "$cn" - [[ $? -eq 0 ]] && cn_match=8 - done <<< "$cns" - subret+=$cn_match - return $subret -} - -# This function determines whether the certificate (arg3) contains "visibility -# information" (see Section 4.3.3 of -# https://www.etsi.org/deliver/etsi_ts/103500_103599/10352303/01.02.01_60/ts_10352303v010201p.pdf. -etsi_ets_visibility_info() { - local jsonID="$1" - local spaces="$2" - local cert="$3" - local cert_txt="$4" - local dercert tag - local -a fingerprint=() access_description=() - local -i i j len len1 len_name nr_visnames=0 - - # If "visibility information" is present, it will appear in the subjectAltName - # extension (0603551D11) as an otherName with OID 0.4.0.3523.3.1 (060604009B430301). - # OpenSSL 1.1.1 and earlier displays all names of type otherName as "othername:". - # As certificates will rarely include a name encoded as an otherName, check the - # text version of the certificate for "othername:" before calling - # external functions to obtain the DER encoded certificate. - if [[ "$cert_txt" =~ X509v3\ Subject\ Alternative\ Name:.*othername:\ ]] || \ - [[ "$cert_txt" =~ X509v3\ Subject\ Alternative\ Name:.*othername:\ 0.4.0.3523.3.1 ]]; then - dercert="$($OPENSSL x509 -outform DER 2>>$ERRFILE <<< "$cert" | hexdump -v -e '16/1 "%02X"')" - if [[ "$dercert" =~ 0603551D110101FF04[0-9A-F]*060604009B430301 ]] || \ - [[ "$dercert" =~ 0603551D1104[0-9A-F]*060604009B430301 ]]; then - # Look for the beginning of the subjectAltName extension. It - # will begin with the OID (2.5.29.17 = 0603551D11). After the OID - # there may be an indication that the extension is critical (0101FF). - # Finally will be the tag indicating that the value of the extension is - # encoded as an OCTET STRING (04). - if [[ "$dercert" =~ 0603551D110101FF04 ]]; then - dercert="${dercert##*0603551D110101FF04}" - else - dercert="${dercert##*0603551D1104}" - fi - # Skip over the encoding of the length of the OCTET STRING. - if [[ "${dercert:0:1}" == 8 ]]; then - i="${dercert:1:1}" - i=2*$i+2 - dercert="${dercert:i}" - else - dercert="${dercert:2}" - fi - # Next byte should be a 30 (SEQUENCE). - if [[ "${dercert:0:2}" == 30 ]]; then - # Get the length of the subjectAltName extension and then skip - # over the encoding of the length. - if [[ "${dercert:2:1}" == 8 ]]; then - case "${dercert:3:1}" in - 1) len=2*0x${dercert:4:2}; dercert="${dercert:6}" ;; - 2) len=2*0x${dercert:4:4}; dercert="${dercert:8}" ;; - 3) len=2*0x${dercert:4:6}; dercert="${dercert:10}" ;; - *) len=0 ;; - esac - else - len=2*0x${dercert:2:2} - dercert="${dercert:4}" - fi - if [[ $len -ne 0 ]] && [[ $len -lt ${#dercert} ]]; then - # loop through all the names and extract the visibility information - for (( i=0; i < len; i+=len_name )); do - tag="${dercert:i:2}" - i+=2 - if [[ "${dercert:i:1}" == 8 ]]; then - i+=1 - case "${dercert:i:1}" in - 1) i+=1; len_name=2*0x${dercert:i:2}; i+=2 ;; - 2) i+=1; len_name=2*0x${dercert:i:4}; i+=4 ;; - 3) i+=1; len_name=2*0x${dercert:i:6}; i+=4 ;; - *) len=0 ;; - esac - else - len_name=2*0x${dercert:i:2} - i+=2 - fi - [[ "$tag" == A0 ]] || continue - # This is an otherName. - [[ $len_name -gt 16 ]] || continue - [[ "${dercert:i:16}" == 060604009B430301 ]] || continue - # According to the OID, this is visibility information. - j=$i+16 - # Skip over the tag (A0) and length for the otherName value. - [[ "${dercert:j:2}" == A0 ]] || continue - j+=2 - if [[ "${dercert:j:1}" == 8 ]]; then - j+=1 - j+=2*0x${dercert:j:1}+1 - else - j+=2 - fi - # The value for this otherName is encoded as a SEQUENCE (30): - # VisibilityInformation ::= SEQUENCE { - # fingerprint OCTET STRING (SIZE(10)), - # accessDescription UTF8String } - [[ "${dercert:j:2}" == 30 ]] || continue - j+=2 - if [[ "${dercert:j:1}" == 8 ]]; then - j+=1 - case "${dercert:j:1}" in - 1) j+=1; len1=2*0x${dercert:j:2}; j+=2 ;; - 2) j+=1; len1=2*0x${dercert:j:4}; j+=4 ;; - 3) j+=1; len1=2*0x${dercert:j:6}; j+=6 ;; - 4) len1=0 ;; - esac - else - len1=2*0x${dercert:j:2} - j+=2 - fi - [[ $len1 -ne 0 ]] || continue - # Next is the 10-byte fingerprint, encoded as an OCTET STRING (04) - [[ "${dercert:j:4}" == 040A ]] || continue - j+=4 - fingerprint[nr_visnames]="$(hex2binary "${dercert:j:20}")" - j+=20 - # Finally comes the access description, encoded as a UTF8String (0C). - [[ "${dercert:j:2}" == 0C ]] || continue - j+=2 - if [[ "${dercert:j:1}" == "8" ]]; then - j+=1 - case "${dercert:j:1}" in - 1) j+=1; len1=2*0x${dercert:j:2}; j+=2 ;; - 2) j+=1; len1=2*0x${dercert:j:4}; j+=4 ;; - 3) j+=1; len1=2*0x${dercert:j:6}; j+=6 ;; - 4) len1=0 ;; - esac - else - len1=2*0x${dercert:j:2} - j+=2 - fi - access_description[nr_visnames]=""$(hex2binary "${dercert:j:len1}")"" - nr_visnames+=1 - done - fi - fi - fi - fi - if [[ $nr_visnames -eq 0 ]]; then - outln "not present" - fileout "$jsonID" "INFO" "not present" - else - for (( i=0; i < nr_visnames; i++ )); do - [[ $i -ne 0 ]] && out "$spaces" - outln "$(out_row_aligned_max_width "${fingerprint[i]} / ${access_description[i]}" "$spaces" $TERM_WIDTH)" - fileout "$jsonID" "INFO" "${fingerprint[i]} / ${access_description[i]}" - done - fi - return 0 -} - -# NOTE: arg3 must contain the text output of $HOSTCERT. -must_staple() { - local jsonID="cert_mustStapleExtension" - local json_postfix="$1" - local provides_stapling="$2" - local hostcert_txt="$3" - local cert extn - local -i extn_len - local supported=false - - # Note this function is only looking for status_request (5) and not - # status_request_v2 (17), since OpenSSL seems to only include status_request (5) - # in its ClientHello when the "-status" option is used. - - # OpenSSL 1.1.0 supports pretty-printing the "TLS Feature extension." For any - # previous versions of OpenSSL, OpenSSL can only show if the extension OID is present. - if grep -A 1 "TLS Feature:" <<< "$hostcert_txt" | grep -q "status_request"; then - # FIXME: This will indicate that must staple is supported if the - # certificate indicates status_request or status_request_v2. This is - # probably okay, since it seems likely that any TLS Feature extension - # that includes status_request_v2 will also include status_request. - supported=true - elif [[ "$hostcert_txt" =~ '1.3.6.1.5.5.7.1.24:' ]]; then - cert="$($OPENSSL x509 -in "$HOSTCERT" -outform DER 2>>$ERRFILE | hexdump -v -e '16/1 "%02X"')" - extn="${cert##*06082B06010505070118}" - # Check for critical bit, and skip over it if present. - [[ "${extn:0:6}" == "0101FF" ]] && extn="${extn:6}" - # Next is tag and length of extnValue OCTET STRING. Assume it is less than 128 bytes. - extn="${extn:4}" - # The TLS Feature is a SEQUENCE of INTEGER. Get the length of the SEQUENCE - extn_len=2*$(hex2dec "${extn:2:2}") - # If the extension include the status_request (5), then it supports must staple. - if [[ "${extn:4:extn_len}" =~ 020105 ]]; then - supported=true - fi - fi - - if "$supported"; then - if "$provides_stapling"; then - prln_svrty_good "supported" - fileout "${jsonID}${json_postfix}" "OK" "supported" - else - prln_svrty_high "requires OCSP stapling (NOT ok)" - fileout "${jsonID}${json_postfix}" "HIGH" "extension detected but no OCSP stapling provided" - fi - else - outln "--" - fileout "${jsonID}${json_postfix}" "INFO" "--" - fi - return 0 -} - -# TODO: This function checks for Certificate Transparency support based on RFC 6962. -# It will need to be updated to add checks for Certificate Transparency support based on 6962bis. -# return values are results, no error conditions -certificate_transparency() { - local cert_txt="$1" - local ocsp_response="$2" - local -i number_of_certificates=$3 - local cipher="$4" - local sni_used="$5" - local tls_version="$6" - local sni="" - local ciphers="" - local extra_extns="" - local -i success - # Cipher suites that use a certificate with an RSA (signature) public key - local -r a_rsa="cc,13, cc,15, c0,30, c0,28, c0,14, 00,9f, cc,a8, cc,aa, c0,a3, c0,9f, 00,6b, 00,39, c0,77, 00,c4, 00,88, c0,45, c0,4d, c0,53, c0,61, c0,7d, c0,8b, 16,b7, 16,b9, c0,2f, c0,27, c0,13, 00,9e, c0,a2, c0,9e, 00,67, 00,33, c0,76, 00,be, 00,9a, 00,45, c0,44, c0,4c, c0,52, c0,60, c0,7c, c0,8a, c0,11, c0,12, 00,16, 00,15, 00,14, c0,10" - # Cipher suites that use a certificate with an RSA (encryption) public key - local -r e_rsa="00,b7, c0,99, 00,ad, cc,ae, 00,9d, c0,a1, c0,9d, 00,3d, 00,35, 00,c0, 00,84, 00,95, c0,3d, c0,51, c0,69, c0,6f, c0,7b, c0,93, ff,01, 00,ac, c0,a0, c0,9c, 00,9c, 00,3c, 00,2f, 00,ba, 00,b6, 00,96, 00,41, c0,98, 00,07, 00,94, c0,3c, c0,50, c0,68, c0,6e, c0,7a, c0,92, 00,05, 00,04, 00,92, 00,0a, 00,93, fe,ff, ff,e0, 00,62, 00,09, 00,61, fe,fe, ff,e1, 00,64, 00,60, 00,08, 00,06, 00,03, 00,b9, 00,b8, 00,2e, 00,3b, 00,02, 00,01, ff,00" - # Cipher suites that use a certificate with a DSA public key - local -r a_dss="00,a3, 00,6a, 00,38, 00,c3, 00,87, c0,43, c0,57, c0,81, 00,a2, 00,40, 00,32, 00,bd, 00,99, 00,44, c0,42, c0,56, c0,80, 00,66, 00,13, 00,63, 00,12, 00,65, 00,11" - # Cipher suites that use a certificate with a DH public key - local -r a_dh="00,a5, 00,a1, 00,69, 00,68, 00,37, 00,36, 00,c2, 00,c1, 00,86, 00,85, c0,3f, c0,41, c0,55, c0,59, c0,7f, c0,83, 00,a4, 00,a0, 00,3f, 00,3e, 00,31, 00,30, 00,bc, 00,bb, 00,98, 00,97, 00,43, 00,42, c0,3e, c0,40, c0,54, c0,58, c0,7e, c0,82, 00,10, 00,0d, 00,0f, 00,0c, 00,0b, 00,0e" - # Cipher suites that use a certificate with an ECDH public key - local -r a_ecdh="c0,32, c0,2e, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, c0,4b, c0,4f, c0,5f, c0,63, c0,89, c0,8d, c0,31, c0,2d, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, c0,4a, c0,4e, c0,5e, c0,62, c0,88, c0,8c, c0,0c, c0,02, c0,0d, c0,03, c0,0b, c0,01" - # Cipher suites that use a certificate with an ECDSA public key - local -r a_ecdsa="cc,14, c0,2c, c0,24, c0,0a, cc,a9, c0,af, c0,ad, c0,73, c0,49, c0,5d, c0,87, 16,b8, 16,ba, c0,2b, c0,23, c0,09, c0,ae, c0,ac, c0,72, c0,48, c0,5c, c0,86, c0,07, c0,08, c0,06" - # Cipher suites that use a certificate with a GOST public key - local -r a_gost="00,80, 00,81, 00,82, 00,83" - - CERTIFICATE_TRANSPARENCY_SOURCE="" - - # First check whether signed certificate timestamps (SCT) are included in the - # server's certificate. If they aren't, check whether the server provided - # a stapled OCSP response with SCTs. If no SCTs were found in the certificate - # or OCSP response, check for an SCT TLS extension. - if [[ "$cert_txt" =~ CT\ Precertificate\ SCTs ]] || [[ "$cert_txt" =~ '1.3.6.1.4.1.11129.2.4.2' ]]; then - CERTIFICATE_TRANSPARENCY_SOURCE="certificate extension" - return 0 - fi - if [[ "$ocsp_response" =~ CT\ Certificate\ SCTs ]] || [[ "$ocsp_response" =~ '1.3.6.1.4.1.11129.2.4.5' ]]; then - CERTIFICATE_TRANSPARENCY_SOURCE="OCSP extension" - return 0 - fi - - # If the server only has one certificate, then it is sufficient to check whether - # determine_tls_extensions() discovered an SCT TLS extension. If the server has more than - # one certificate, then it is possible that an SCT TLS extension is returned for some - # certificates, but not for all of them. - if [[ $number_of_certificates -eq 1 ]] && [[ "$TLS_EXTENSIONS" =~ signed\ certificate\ timestamps ]]; then - CERTIFICATE_TRANSPARENCY_SOURCE="TLS extension" - return 0 - fi - - if [[ $number_of_certificates -gt 1 ]] && ! "$SSL_NATIVE"; then - if [[ "$tls_version" == 0304 ]]; then - ciphers=", 13,01, 13,02, 13,03, 13,04, 13,05" - if [[ "$cipher" == tls1_3_RSA ]]; then - extra_extns=", 00,0d,00,10,00,0e,08,04,08,05,08,06,04,01,05,01,06,01,02,01" - elif [[ "$cipher" == tls1_3_ECDSA ]]; then - extra_extns=", 00,0d,00,0a,00,08,04,03,05,03,06,03,02,03" - else - return 1 - fi - else - [[ "$cipher" =~ aRSA ]] && ciphers+=", $a_rsa" - [[ "$cipher" =~ eRSA ]] && ciphers+=", $e_rsa" - [[ "$cipher" =~ aDSS ]] && ciphers+=", $a_dss" - [[ "$cipher" =~ aDH ]] && ciphers+=", $a_dh" - [[ "$cipher" =~ aECDH ]] && ciphers+=", $a_ecdh" - [[ "$cipher" =~ aECDSA ]] && ciphers+=", $a_ecdsa" - [[ "$cipher" =~ aGOST ]] && ciphers+=", $a_gost" - - [[ -z "$ciphers" ]] && return 1 - ciphers+=", 00,ff" - fi - [[ -z "$sni_used" ]] && sni="$SNI" && SNI="" - tls_sockets "${tls_version:2:2}" "${ciphers:2}" "all" "00,12,00,00$extra_extns" - success=$? - [[ -z "$sni_used" ]] && SNI="$sni" - if [[ $success -eq 0 || $success -eq 2 ]] && \ - grep -a 'TLS server extension ' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" | \ - grep -aq "signed certificate timestamps"; then - CERTIFICATE_TRANSPARENCY_SOURCE="TLS extension" - return 0 - fi - fi - - if [[ $SERVICE != HTTP ]] && [[ "$CLIENT_AUTH" != required ]]; then - # At the moment Certificate Transparency only applies to HTTPS. - CERTIFICATE_TRANSPARENCY_SOURCE="N/A" - else - CERTIFICATE_TRANSPARENCY_SOURCE="--" - fi - return 0 -} - -# Shortcut for $OPENSSL x509 -noout -in $cert $ossl_command -# arg1 is the certificate -# arg2 is -serial | -fingerprint -sha1 | -fingerprint -sha256 -# returns the serial or fingerprint as ASCII -# -determine_cert_fingerprint_serial() { - local cert="$1" - local ossl_command="$2" - local result="" - - result="$($OPENSSL x509 -noout $ossl_command 2>>$ERRFILE <<< "$cert")" - # remove strings in text output, colon only appear in fingerprints - result="${result//Fingerprint=}" - result="${result//serial=}" - result="${result//:/}" - result="${result//SHA1 /}" - result="${result//sha1 /}" - result="${result//SHA256 /}" - result="${result//sha256 /}" - # When the serial number is too large we'll get a 0x0a LF after 70 ASCII chars (see #2010). - # Thus we clean them here so that it is displayed correctly. - result="${result/[$'\n\r']/}" - result="${result//[\\]/}" - safe_echo "$result" -} - -# Returns startdate, enddate, diffseconds, days2expire as CSVs as strings -# arg1: human readable text string for certificate (openssl x509 -text -noout) -# -determine_dates_certificate() { - local cert_txt="$1" - local startdate enddate yearnow y m d yearstart clockstart yearend clockend - local diffseconds=0 days2expire=0 - local -i secsaday=86400 - - startdate="${cert_txt#*Validity*Not Before: }" - # FreeBSD + OSX can't swallow the leading blank: - startdate="${startdate%%GMT*}GMT" - enddate="${cert_txt#*Validity*Not Before: *Not After : }" - enddate="${enddate%%GMT*}GMT" - # Now we have a normalized enddate and startdate like "Feb 27 10:03:20 2017 GMT" -- also for OpenBSD - if "$HAS_OPENBSDDATE"; then - # Best we want to do under old versions of OpenBSD, first just remove the GMT and keep start/endate for later output - startdate="$(parse_date "$startdate" "+%s")" - enddate="$(parse_date "$enddate" "+%s")" - # Now we extract a date block and a time block which we need for later output - startdate="$(parse_date "$startdate" +"%F %H:%M" "%b %d %T %Y %Z")" - enddate="$(parse_date "$enddate" +"%F %H:%M" "%b %d %T %Y %Z")" - read -r yearstart clockstart <<< "$startdate" - read -r yearend clockend <<< "$enddate" - debugme echo "$yearstart, $clockstart" - debugme echo "$yearend, $clockend" - y=$(( ${yearend:0:4} - ${yearstart:0:4} )) - m=$(( ${yearend:5:1} - ${yearstart:5:1} + ${yearend:6:1} - ${yearstart:6:1} )) - d=$(( ${yearend:8:2} - ${yearstart:8:2} )) - # We take the year, month, days here as old OpenBSD's date is too difficult for real conversion - # see comment in parse_date(). In diffseconds then we have the estimated absolute validity period - diffseconds=$(( d + ((m*30)) + ((y*365)) )) - diffseconds=$((diffseconds * secsaday)) - # Now we estimate the days left plus length of month/year: - yearnow="$(date -juz GMT "+%Y-%m-%d %H:%M")" - y=$(( ${yearend:0:4} - ${yearnow:0:4} )) - m=$(( ${yearend:5:1} - ${yearnow:5:1} + ${yearend:6:1} - ${yearnow:6:1} )) - d=$(( ${yearend:8:2} - ${yearnow:8:2} )) - days2expire=$(( d + ((m*30)) + ((y*365)) )) - else - startdate="$(parse_date "$startdate" +"%F %H:%M" "%b %d %T %Y %Z")" - enddate="$(parse_date "$enddate" +"%F %H:%M" "%b %d %T %Y %Z")" - days2expire=$(( $(parse_date "$enddate" "+%s" $'%F %H:%M') - $(LC_ALL=C date "+%s") )) # first in seconds - days2expire=$((days2expire / secsaday)) - diffseconds=$(( $(parse_date "$enddate" "+%s" $'%F %H:%M') - $(parse_date "$startdate" "+%s" $'%F %H:%M') )) - fi - safe_echo "$startdate,$enddate,$diffseconds,$days2expire,$yearstart" -} - - - -certificate_info() { - local proto - local -i certificate_number=$1 - local -i number_of_certificates=$2 - local cert_txt="$3" - local intermediates="$4" - local cipher=$5 - local cert_keysize=$6 - local cert_type="$7" - local ocsp_response_binary="$8" - local ocsp_response=$9 - local ocsp_response_status=${10} - local sni_used="${11}" - local ct="${12}" - local certificate_list_ordering_problem="${13}" - local cert_sig_algo cert_sig_hash_algo cert_key_algo cert_spki_info - local hostcert="" - local common_primes_file="$TESTSSL_INSTALL_DIR/etc/common-primes.txt" - local -i lineno_matched=0 - local cert_keyusage cert_ext_keyusage short_keyAlgo - local outok=true - local days2expire ocsp_uri crl - local startdate enddate issuer_CN issuer_C issuer_O issuer sans san all_san="" cn - local issuer_DC issuerfinding cn_nosni="" - local cert_fingerprint_sha1 cert_fingerprint_sha2 cert_serial cert - local -a intermediate_certs_txt=() - local policy_oid - local spaces="" - local -i trust_sni=0 trust_nosni=0 diffseconds=0 - local has_dns_sans has_dns_sans_nosni - local trust_sni_finding - local -i i certificates_provided=0 - local cn_finding trustfinding trustfinding_nosni - local cnok="OK" - local expfinding expok="OK" - local -i ret=0 tmp=0 - local json_postfix="" # string to place at the end of JSON IDs when there is more than one certificate - local jsonID="" # string to place at beginning of JSON IDs - local json_rating json_msg - local indent="" - local days2warn2=$DAYS2WARN2 - local days2warn1=$DAYS2WARN1 - local provides_stapling=false - local caa_node="" all_caa="" caa_property_name="" caa_property_value="" - local response="" - local yearstart - local gt_398=false gt_398warn=false - local gt_825=false gt_825warn=false - local -i secsaday=86400 - local first=true - local badocsp=1 - local len_cert_serial=0 - - if [[ $number_of_certificates -gt 1 ]]; then - [[ $certificate_number -eq 1 ]] && outln - indent=" " - out "$indent" - pr_headline "Server Certificate #$certificate_number" - [[ -z "$sni_used" ]] && pr_underline " (in response to request w/o SNI)" - outln - json_postfix=" " - spaces=" " - else - spaces=" " - fi - - GOOD_CA_BUNDLE="" - cert_sig_algo="$(awk -F':' '/Signature Algorithm/ { print $2; if (++Match >= 1) exit; }' <<< "$cert_txt")" - cert_sig_algo="${cert_sig_algo// /}" - case "$cert_sig_algo" in - 1.3.101.112|ED25519) cert_sig_algo="Ed25519" ;; - 1.3.101.113|ED448) cert_sig_algo="Ed448" ;; - esac - cert_key_algo="$(awk -F':' '/Public Key Algorithm:/ { print $2; if (++Match >= 1) exit; }' <<< "$cert_txt")" - cert_key_algo="${cert_key_algo// /}" - case "$cert_key_algo" in - 1.3.101.112|E[Dd]25519) cert_key_algo="Ed25519"; cert_keysize=253 ;; - 1.3.101.113|E[Dd]448) cert_key_algo="Ed448"; cert_keysize=456 ;; - esac - - out "$indent" ; pr_bold " Signature Algorithm " - jsonID="cert_signatureAlgorithm" - case $cert_sig_algo in - sha1WithRSA|sha1WithRSAEncryption) - pr_svrty_medium "SHA1 with RSA" - if [[ "$SERVICE" == HTTP ]] || "$ASSUME_HTTP"; then - out " -- besides: users will receive a "; pr_svrty_high "strong browser WARNING" - fi - outln - fileout "${jsonID}${json_postfix}" "MEDIUM" "SHA1 with RSA" - set_grade_cap "T" "Uses SHA1 algorithm" - ;; - sha224WithRSAEncryption) - outln "SHA224 with RSA" - fileout "${jsonID}${json_postfix}" "INFO" "SHA224 with RSA" - ;; - sha256WithRSAEncryption) - prln_svrty_good "SHA256 with RSA" - fileout "${jsonID}${json_postfix}" "OK" "SHA256 with RSA" - ;; - sha384WithRSAEncryption) - prln_svrty_good "SHA384 with RSA" - fileout "${jsonID}${json_postfix}" "OK" "SHA384 with RSA" - ;; - sha512WithRSAEncryption) - prln_svrty_good "SHA512 with RSA" - fileout "${jsonID}${json_postfix}" "OK" "SHA512 with RSA" - ;; - ecdsa-with-SHA1) - prln_svrty_medium "ECDSA with SHA1" - fileout "${jsonID}${json_postfix}" "MEDIUM" "ECDSA with SHA1" - set_grade_cap "T" "Uses SHA1 algorithm" - ;; - ecdsa-with-SHA224) - outln "ECDSA with SHA224" - fileout "${jsonID}${json_postfix}" "INFO" "ECDSA with SHA224" - ;; - ecdsa-with-SHA256) - prln_svrty_good "ECDSA with SHA256" - fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA256" - ;; - ecdsa-with-SHA384) - prln_svrty_good "ECDSA with SHA384" - fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA384" - ;; - ecdsa-with-SHA512) - prln_svrty_good "ECDSA with SHA512" - fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA512" - ;; - dsaWithSHA1) - prln_svrty_medium "DSA with SHA1" - fileout "${jsonID}${json_postfix}" "MEDIUM" "DSA with SHA1" - set_grade_cap "T" "Uses SHA1 algorithm" - ;; - dsa_with_SHA224) - outln "DSA with SHA224" - fileout "${jsonID}${json_postfix}" "INFO" "DSA with SHA224" - ;; - dsa_with_SHA256) - prln_svrty_good "DSA with SHA256" - fileout "${jsonID}${json_postfix}" "OK" "DSA with SHA256" - ;; - rsassaPss) - cert_sig_hash_algo="$(awk '/Signature Algorithm/ { getline; print $0; exit }' <<< "$cert_txt" | sed 's/^.*Hash Algorithm: //')" - case $cert_sig_hash_algo in - sha1) - prln_svrty_medium "RSASSA-PSS with SHA1" - fileout "${jsonID}${json_postfix}" "MEDIUM" "RSASSA-PSS with SHA1" - set_grade_cap "T" "Uses SHA1 algorithm" - ;; - sha224) - outln "RSASSA-PSS with SHA224" - fileout "${jsonID}${json_postfix}" "INFO" "RSASSA-PSS with SHA224" - ;; - sha256) - prln_svrty_good "RSASSA-PSS with SHA256" - fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA256" - ;; - sha384) - prln_svrty_good "RSASSA-PSS with SHA384" - fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA384" - ;; - sha512) - prln_svrty_good "RSASSA-PSS with SHA512" - fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA512" - ;; - *) - out "RSASSA-PSS with $cert_sig_hash_algo" - prln_warning " (Unknown hash algorithm)" - fileout "${jsonID}${json_postfix}" "DEBUG" "RSASSA-PSS with $cert_sig_hash_algo" - esac - ;; - md2*) - prln_svrty_critical "MD2" - fileout "${jsonID}${json_postfix}" "CRITICAL" "MD2" - set_grade_cap "F" "Supports a insecure signature (MD2)" - ;; - md4*) - prln_svrty_critical "MD4" - fileout "${jsonID}${json_postfix}" "CRITICAL" "MD4" - ;; - md5*) - prln_svrty_critical "MD5" - fileout "${jsonID}${json_postfix}" "CRITICAL" "MD5" - set_grade_cap "F" "Supports a insecure signature (MD5)" - ;; - Ed25519|Ed448) - prln_svrty_good "$cert_sig_algo" - fileout "${jsonID}${json_postfix}" "OK" "$cert_sig_algo" - ;; - *) - out "$cert_sig_algo (" - pr_warning "FIXME: can't tell whether this is good or not" - outln ")" - fileout "${jsonID}${json_postfix}" "DEBUG" "$cert_sig_algo" - ((ret++)) - ;; - esac - # old, but still interesting: https://blog.hboeck.de/archives/754-Playing-with-the-EFF-SSL-Observatory.html - - out "$indent"; pr_bold " Server key size " - jsonID="cert_keySize" - if [[ -z "$cert_keysize" ]]; then - outln "(couldn't determine)" - fileout "${jsonID}${json_postfix}" "cannot be determined" - ((ret++)) - else - case $cert_key_algo in - *RSA*|*rsa*) short_keyAlgo="RSA";; - *ecdsa*|*ecPublicKey) short_keyAlgo="EC";; - *Ed25519*|*Ed448*) short_keyAlgo="EdDSA";; - *DSA*|*dsa*) short_keyAlgo="DSA";; - *GOST*|*gost*) short_keyAlgo="GOST";; - *dh*|*DH*) short_keyAlgo="DH" ;; - *) pr_fixme "don't know $cert_key_algo " - ((ret++)) ;; - esac - out "$short_keyAlgo " - # https://tools.ietf.org/html/rfc4492, https://www.keylength.com/en/compare/ - # https://doi.org/10.1007/s00145-001-0009-4 - # see https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-4/final - # Table 2 @ chapter 5.6.1 (~ p66) - if [[ $cert_key_algo =~ ecdsa ]] || [[ $cert_key_algo =~ ecPublicKey ]]; then - if [[ "$cert_keysize" -le 110 ]]; then # a guess - pr_svrty_critical "$cert_keysize" - json_rating="CRITICAL"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 123 ]]; then # a guess - pr_svrty_high "$cert_keysize" - json_rating="HIGH"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 163 ]]; then - pr_svrty_medium "$cert_keysize" - json_rating="MEDIUM"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 224 ]]; then - out "$cert_keysize" - json_rating="INFO"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 533 ]]; then - pr_svrty_good "$cert_keysize" - json_rating="OK"; json_msg="$short_keyAlgo $cert_keysize bits" - else - out "keysize: $cert_keysize (not expected, FIXME)" - json_rating="DEBUG"; json_msg=" $cert_keysize bits (not expected)" - ((ret++)) - fi - out " bits" - - set_key_str_score "$short_keyAlgo" "$cert_keysize" - elif [[ $cert_key_algo =~ RSA ]] || [[ $cert_key_algo =~ rsa ]] || [[ $cert_key_algo =~ dsa ]] || \ - [[ $cert_key_algo =~ dhKeyAgreement ]] || [[ $cert_key_algo == X9.42\ DH ]]; then - if [[ "$cert_keysize" -le 512 ]]; then - pr_svrty_critical "$cert_keysize" - out " bits" - json_rating="CRITICAL"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 768 ]]; then - pr_svrty_high "$cert_keysize" - out " bits" - json_rating="HIGH"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 1024 ]]; then - pr_svrty_medium "$cert_keysize" - out " bits" - json_rating="MEDIUM"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 2048 ]]; then - out "$cert_keysize bits" - json_rating="INFO"; json_msg="$short_keyAlgo $cert_keysize bits" - elif [[ "$cert_keysize" -le 4096 ]]; then - pr_svrty_good "$cert_keysize" - json_rating="OK"; json_msg="$short_keyAlgo $cert_keysize bits" - out " bits" - else - pr_warning "weird key size: $cert_keysize bits"; out " (could cause compatibility problems)" - json_rating="WARN"; json_msg="$cert_keysize bits (Odd)" - ((ret++)) - fi - - set_key_str_score "$short_keyAlgo" "$cert_keysize" - elif [[ $cert_key_algo == Ed* ]]; then - pr_svrty_good "$cert_key_algo" - json_rating="OK"; json_msg="$short_keyAlgo $cert_key_algo" - set_key_str_score "$short_keyAlgo" "$cert_keysize" - else - out "$cert_key_algo + $cert_keysize bits (" - pr_warning "FIXME: can't tell whether this is good or not" - out ")" - json_rating="WARN"; json_msg="Server keys $cert_keysize bits, unknown public key algorithm $cert_key_algo" - ((ret++)) - fi - fi - - case "$short_keyAlgo" in - "RSA") cert_spki_info="${cert_txt##*Subject Public Key Info:}" - cert_spki_info="${cert_spki_info##*Public Key Algorithm:}" - cert_spki_info="${cert_spki_info#*Exponent:}" - cert_spki_info="$(strip_leading_space "$cert_spki_info")" - cert_spki_info="${cert_spki_info%%[[:space:]]*}" - if [[ -n "$cert_spki_info" ]]; then - if [[ $cert_spki_info -eq 1 ]]; then - out " (exponent is "; pr_svrty_critical "$cert_spki_info"; out ")" - json_rating="CRITICAL" - set_grade_cap "F" "RSA certificate uses exponent of 1" - else - out " (exponent is $cert_spki_info)" - fi - json_msg+=" (exponent is $cert_spki_info)" - fi - ;; - "EC") cert_spki_info="${cert_txt##*Subject Public Key Info:}" - cert_spki_info="${cert_spki_info##*Public Key Algorithm:}" - cert_spki_info="${cert_spki_info##*ASN1 OID: }" - [[ "$cert_spki_info" =~ NIST\ CURVE:\ ]] && cert_spki_info="${cert_spki_info##*NIST CURVE: }" - cert_spki_info="${cert_spki_info%%[[:space:]]*}" - cert_spki_info="$(strip_lf "$(strip_spaces "$cert_spki_info")")" - if [[ -n "$cert_spki_info" ]]; then - out " (curve $cert_spki_info)" - json_msg+=" (curve $cert_spki_info)" - fi - ;; - "DH") if [[ -s "$common_primes_file" ]]; then - cert_spki_info="${cert_txt##*Subject Public Key Info:}" - cert_spki_info="${cert_spki_info##*Public Key Algorithm:}" - cert_spki_info="$(awk '/prime:|P:/,/generator:|G:/' <<< "$cert_spki_info" | grep -Ev "prime|P:|generator|G:")" - cert_spki_info="$(strip_spaces "$(colon_to_spaces "$(newline_to_spaces "$cert_spki_info")")")" - [[ "${cert_spki_info:0:2}" == 00 ]] && cert_spki_info="${cert_spki_info:2}" - cert_spki_info="$(toupper "$cert_spki_info")" - lineno_matched=$(grep -n "$cert_spki_info" "$common_primes_file" 2>/dev/null | awk -F':' '{ print $1 }') - if [[ "$lineno_matched" -ne 0 ]]; then - cert_spki_info="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" - out " ($cert_spki_info)" - json_msg+=" ($cert_spki_info)" - fi - fi - ;; - esac - outln - fileout "${jsonID}${json_postfix}" "$json_rating" "$json_msg" - - out "$indent"; pr_bold " Server key usage "; - outok=true - jsonID="cert_keyUsage" - cert_keyusage="$(strip_leading_space "$(awk '/X509v3 Key Usage:/ { getline; print $0 }' <<< "$cert_txt")")" - if [[ -n "$cert_keyusage" ]]; then - outln "$cert_keyusage" - if [[ " $cert_type " =~ \ RSASig\ || " $cert_type " =~ \ DSA\ || " $cert_type " =~ \ ECDSA\ || " $cert_type " =~ \ EdDSA\ ]] && \ - [[ ! "$cert_keyusage" =~ Digital\ Signature ]]; then - prln_svrty_high "$indent Certificate incorrectly used for digital signatures" - fileout "${jsonID}${json_postfix}" "HIGH" "Certificate incorrectly used for digital signatures: \"$cert_keyusage\"" - outok=false - fi - if [[ " $cert_type " =~ \ RSAKMK\ ]] && [[ ! "$cert_keyusage" =~ Key\ Encipherment ]]; then - prln_svrty_high "$indent Certificate incorrectly used for key encipherment" - fileout "${jsonID}${json_postfix}" "HIGH" "Certificate incorrectly used for key encipherment: \"$cert_keyusage\"" - outok=false - fi - if [[ " $cert_type " =~ \ DH\ || " $cert_type " =~ \ ECDH\ ]] && \ - [[ ! "$cert_keyusage" =~ Key\ Agreement ]]; then - prln_svrty_high "$indent Certificate incorrectly used for key agreement" - fileout "${jsonID}${json_postfix}" "HIGH" "Certificate incorrectly used for key agreement: \"$cert_keyusage\"" - outok=false - fi - else - outln "--" - fileout "${jsonID}${json_postfix}" "INFO" "No server key usage information" - outok=false - fi - if "$outok"; then - fileout "${jsonID}${json_postfix}" "INFO" "$cert_keyusage" - fi - - out "$indent"; pr_bold " Server extended key usage "; - jsonID="cert_extKeyUsage" - outok=true - cert_ext_keyusage="$(strip_leading_space "$(awk '/X509v3 Extended Key Usage:/ { getline; print $0 }' <<< "$cert_txt")")" - if [[ -n "$cert_ext_keyusage" ]]; then - outln "$cert_ext_keyusage" - if [[ ! "$cert_ext_keyusage" =~ "TLS Web Server Authentication" ]] && [[ ! "$cert_ext_keyusage" =~ "Any Extended Key Usage" ]]; then - prln_svrty_high "$indent Certificate incorrectly used for TLS Web Server Authentication" - fileout "${jsonID}${json_postfix}" "HIGH" "Certificate incorrectly used for TLS Web Server Authentication: \"$cert_ext_keyusage\"" - outok=false - fi - else - outln "--" - fileout "${jsonID}${json_postfix}" "INFO" "No server extended key usage information" - outok=false - fi - if "$outok"; then - fileout "${jsonID}${json_postfix}" "INFO" "$cert_ext_keyusage" - fi - - hostcert="$(<$HOSTCERT)" - - out "$indent"; pr_bold " Serial " - cert_serial="$(determine_cert_fingerprint_serial "$hostcert" "-serial")" - fileout "cert_serialNumber${json_postfix}" "INFO" "$cert_serial" - out "$cert_serial" - - len_cert_serial=${#cert_serial} - len_cert_serial=$(( len_cert_serial / 2 )) - - if [[ $len_cert_serial -gt 20 ]]; then - # https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.2 - outln - prln_svrty_low "${spaces}NOT ok: length must not exceed 20 bytes (is: $len_cert_serial bytes)" - fileout "cert_serialNumberLen${json_postfix}" "LOW" "$len_cert_serial is too long" - elif [[ $len_cert_serial -lt 8 ]] && [[ $SERVICE == HTTP ]]; then - # We only want this check for browsers as this requirement comes from the CA browser forum, - # see e.g. https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.8.0.pdf - prln_svrty_low " NOT ok: length should be >= 64 bits entropy (is: $len_cert_serial bytes)" - fileout "cert_serialNumberLen${json_postfix}" "LOW" "$len_cert_serial is not enough entropy" - else - outln " (OK: length $len_cert_serial)" - fileout "cert_serialNumberLen${json_postfix}" "INFO" "$len_cert_serial" - fi - - out "$indent"; pr_bold " Fingerprints " - cert_fingerprint_sha1="$(determine_cert_fingerprint_serial "$hostcert" "-fingerprint -sha1")" - outln "SHA1 $cert_fingerprint_sha1" - fileout "cert_fingerprintSHA1${json_postfix}" "INFO" "${cert_fingerprint_sha1}" - - cert_fingerprint_sha2="$(determine_cert_fingerprint_serial "$hostcert" "-fingerprint -sha256")" - fileout "cert_fingerprintSHA256${json_postfix}" "INFO" "${cert_fingerprint_sha2}" - outln "${spaces}SHA256 ${cert_fingerprint_sha2}" - - fileout "cert${json_postfix}" "INFO" "$(pem_to_one_line "$hostcert")" - - [[ -z $CERT_FINGERPRINT_SHA2 ]] && \ - CERT_FINGERPRINT_SHA2="$cert_fingerprint_sha2" || - CERT_FINGERPRINT_SHA2="$cert_fingerprint_sha2 $CERT_FINGERPRINT_SHA2" - [[ -z $RSA_CERT_FINGERPRINT_SHA2 ]] && \ - [[ $cert_key_algo =~ RSA || $cert_key_algo =~ rsa ]] && - RSA_CERT_FINGERPRINT_SHA2="$cert_fingerprint_sha2" - - out "$indent"; pr_bold " Common Name (CN) " - cn_finding="Common Name (CN) : " - cn="$(get_cn_from_cert $HOSTCERT)" - if [[ -n "$cn" ]]; then - pr_italic "$cn" - cn_finding="$cn" - else - cn="no CN field in subject" - out "($cn)" - cn_finding="$cn" - cnok="INFO" - fi - fileout "cert_commonName${json_postfix}" "$cnok" "$cn_finding" - cn_finding="" - - if [[ -n "$sni_used" ]]; then - if grep -qe '-----BEGIN' "$HOSTCERT.nosni"; then - cn_nosni="$(get_cn_from_cert "$HOSTCERT.nosni")" - [[ -z "$cn_nosni" ]] && cn_nosni="no CN field in subject" - fi - debugme tm_out "\"$NODE\" | \"$cn\" | \"$cn_nosni\"" - else - debugme tm_out "\"$NODE\" | \"$cn\"" - fi - - if [[ -z "$sni_used" ]] || [[ "$(toupper "$cn_nosni")" == "$(toupper "$cn")" ]]; then - outln - cn_finding="$cn" - elif [[ -z "$cn_nosni" ]]; then - out " (request w/o SNI didn't succeed"; - cn_finding+="request w/o SNI didn't succeed" - if [[ $cert_sig_algo =~ ecdsa ]]; then - out ", usual for EC certificates" - cn_finding+=", usual for EC certificates" - fi - outln ")" - cn_finding+="" - elif [[ "$cn_nosni" == *"no CN field"* ]]; then - outln ", (request w/o SNI: $cn_nosni)" - cn_finding="$cn_nosni" - else - out " (CN in response to request w/o SNI: "; pr_italic "$cn_nosni"; outln ")" - cn_finding="$cn_nosni" - fi - fileout "cert_commonName_wo_SNI${json_postfix}" "INFO" "$cn_finding" - - sans=$(grep -A2 "Subject Alternative Name" <<< "$cert_txt" | \ - grep -E "DNS:|IP Address:|email:|URI:|DirName:|Registered ID:" | tr ',' '\n' | \ - sed -e 's/ *DNS://g' -e 's/ *IP Address://g' -e 's/ *email://g' -e 's/ *URI://g' -e 's/ *DirName://g' \ - -e 's/ *Registered ID://g' \ - -e 's/ *othername://g' -e 's/ *X400Name://g' -e 's/ *EdiPartyName://g') - # ^^^ CACert - - out "$indent"; pr_bold " subjectAltName (SAN) " - jsonID="cert_subjectAltName" - if [[ -n "$sans" ]]; then - while read san; do - [[ -n "$san" ]] && all_san+="$san " - done <<< "$sans" - prln_italic "$(out_row_aligned_max_width "$all_san" "$indent " $TERM_WIDTH)" - fileout "${jsonID}${json_postfix}" "INFO" "$all_san" - else - if [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then - pr_svrty_high "missing (NOT ok)"; outln " -- Browsers are complaining" - fileout "${jsonID}${json_postfix}" "HIGH" "No SAN, browsers are complaining" - else - pr_svrty_medium "missing"; outln " -- no SAN is deprecated" - fileout "${jsonID}${json_postfix}" "MEDIUM" "Providing no SAN is deprecated" - fi - fi - - # Determine the issuer now as we need them for host certificate warning - issuer="$($OPENSSL x509 -noout -issuer -nameopt multiline,-align,sname,-esc_msb,utf8,-space_eq 2>>$ERRFILE <<< "$hostcert")" - issuer_CN="$(awk -F'=' '/CN=/ { print $2 }' <<< "$issuer")" - issuer_O="$(awk -F'=' '/O=/ { print $2 }' <<< "$issuer")" - issuer_C="$(awk -F'=' '/ C=/ { print $2 }' <<< "$issuer")" - issuer_DC="$(awk -F'=' '/DC=/ { print $2 }' <<< "$issuer")" - - out "$indent"; pr_bold " Trust (hostname) " - compare_server_name_to_cert "$HOSTCERT" - trust_sni=$? - - # Find out if the subjectAltName extension is present and contains - # a DNS name, since Section 6.3 of RFC 6125 says: - # Security Warning: A client MUST NOT seek a match for a reference - # identifier of CN-ID if the presented identifiers include a DNS-ID, - # SRV-ID, URI-ID, or any application-specific identifier types - # supported by the client. - has_dns_sans=$HAS_DNS_SANS - - case $trust_sni in - 0) trustfinding="certificate does not match supplied URI" - set_grade_cap "M" "Domain name mismatch" - ;; - 1) trustfinding="Ok via SAN" ;; - 2) trustfinding="Ok via SAN wildcard" ;; - 4) if "$has_dns_sans"; then - trustfinding="via CN, but not SAN" - else - trustfinding="via CN only" - fi - ;; - 5) trustfinding="Ok via SAN and CN" ;; - 6) trustfinding="Ok via SAN wildcard and CN" - ;; - 8) if "$has_dns_sans"; then - trustfinding="via CN wildcard, but not SAN" - else - trustfinding="via CN (wildcard) only" - fi - ;; - 9) trustfinding="Ok via CN wildcard and SAN" - ;; - 10) trustfinding="Ok via SAN wildcard and CN wildcard" - ;; - esac - - if [[ $trust_sni -eq 0 ]]; then - pr_svrty_high "$trustfinding" - trust_sni_finding="HIGH" - elif [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then - if [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then - # https://bugs.chromium.org/p/chromium/issues/detail?id=308330 - # https://bugzilla.mozilla.org/show_bug.cgi?id=1245280 - # https://www.chromestatus.com/feature/4981025180483584 - pr_svrty_high "$trustfinding"; out " -- Browsers are complaining" - trust_sni_finding="HIGH" - else - pr_svrty_medium "$trustfinding" - trust_sni_finding="MEDIUM" - # we punish CN matching for non-HTTP as it is deprecated https://tools.ietf.org/html/rfc2818#section-3.1 - ! "$has_dns_sans" && out " -- CN only match is deprecated" - fi - else - pr_svrty_good "$trustfinding" - trust_sni_finding="OK" - fi - - if [[ -n "$cn_nosni" ]]; then - compare_server_name_to_cert "$HOSTCERT.nosni" - trust_nosni=$? - has_dns_sans_nosni=$HAS_DNS_SANS - fi - - # See issue #733. - if [[ -z "$sni_used" ]]; then - trustfinding_nosni="" - elif [[ $trust_sni -eq $trust_nosni && "$has_dns_sans" == "$has_dns_sans_nosni" ]] || \ - [[ $trust_sni -eq 0 && $trust_nosni -eq 0 ]]; then - trustfinding_nosni=" (same w/o SNI)" - elif [[ $trust_nosni -eq 0 ]]; then - if [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then - trustfinding_nosni=" (w/o SNI: certificate does not match supplied URI)" - else - trustfinding_nosni=" (SNI mandatory)" - fi - elif [[ $trust_nosni -eq 4 ]] || [[ $trust_nosni -eq 8 ]] || [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then - case $trust_nosni in - 1) trustfinding_nosni=" (w/o SNI: Ok via SAN)" ;; - 2) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard)" ;; - 4) if "$has_dns_sans_nosni"; then - trustfinding_nosni=" (w/o SNI: via CN, but not SAN)" - else - trustfinding_nosni=" (w/o SNI: via CN only)" - fi - ;; - 5) trustfinding_nosni=" (w/o SNI: Ok via SAN and CN)" ;; - 6) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard and CN)" ;; - 8) if "$has_dns_sans_nosni"; then - trustfinding_nosni=" (w/o SNI: via CN wildcard, but not SAN)" - else - trustfinding_nosni=" (w/o SNI: via CN (wildcard) only)" - fi - ;; - 9) trustfinding_nosni=" (w/o SNI: Ok via CN wildcard and SAN)" ;; - 10) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard and CN wildcard)" ;; - esac - elif [[ $trust_sni -ne 0 ]]; then - trustfinding_nosni=" (works w/o SNI)" - else - trustfinding_nosni=" (however, works w/o SNI)" - fi - if [[ -n "$sni_used" ]] || [[ $trust_nosni -eq 0 ]] || [[ $trust_nosni -ne 4 && $trust_nosni -ne 8 ]]; then - outln "$trustfinding_nosni" - elif [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then - prln_svrty_high "$trustfinding_nosni" - else - prln_svrty_medium "$trustfinding_nosni" - fi - - fileout "cert_trust${json_postfix}" "$trust_sni_finding" "${trustfinding}${trustfinding_nosni}" - - out "$indent"; pr_bold " Chain of trust"; out " " - jsonID="cert_chain_of_trust" - # Looks for CA's that have their trust removed by the first part of their Organization Name, add multiple with ^(TrustCor Systems|WoSign) etc. - if [[ "$issuer_O" =~ ^(TrustCor Systems) ]]; then - # Shortcut for this special case here. There is a difference between not being in a root store and being removed from a root store. - pr_italic "$issuer_O"; out " is " ; prln_svrty_critical "actively removed from one or more root stores (NOT ok)" - fileout "${jsonID}${json_postfix}" "CRITICAL" "Issuer removed from one or more root stores ($issuer_O)" - set_grade_cap "T" "Untrusted certificate chain" - else - # Also handles fileout, keep error if happened - determine_trust "$jsonID" "$json_postfix" || ((ret++)) - fi - - # https://fahrplan.events.ccc.de/congress/2010/Fahrplan/attachments/1777_is-the-SSLiverse-a-safe-place.pdf, see p40+ - out "$indent"; pr_bold " EV cert"; out " (experimental) " - jsonID="cert_certificatePolicies_EV" - # only the first one, seldom we have two - policy_oid=$(awk '/ .Policy: / { print $2 }' <<< "$cert_txt" | awk 'NR < 2') - if grep -Eq 'Extended Validation|Extended Validated|EV SSL|EV CA' <<< "$issuer" || \ - [[ 2.16.840.1.114028.10.1.2 == "$policy_oid" ]] || \ - [[ 2.16.840.1.114412.1.3.0.2 == "$policy_oid" ]] || \ - [[ 2.16.840.1.114412.2.1 == "$policy_oid" ]] || \ - [[ 2.16.578.1.26.1.3.3 == "$policy_oid" ]] || \ - [[ 1.3.6.1.4.1.17326.10.14.2.1.2 == "$policy_oid" ]] || \ - [[ 1.3.6.1.4.1.17326.10.8.12.1.2 == "$policy_oid" ]] || \ - [[ 1.3.6.1.4.1.13177.10.1.3.10 == "$policy_oid" ]] ; then - out "yes " - fileout "${jsonID}${json_postfix}" "OK" "yes" - else - out "no " - fileout "${jsonID}${json_postfix}" "INFO" "no" - fi - debugme echo -n "($(newline_to_spaces "$policy_oid"))" - outln -#TODO: check browser OIDs: -# https://dxr.mozilla.org/mozilla-central/source/security/certverifier/ExtendedValidation.cpp -# https://chromium.googlesource.com/chromium/chromium/+/master/net/base/ev_root_ca_metadata.cc -# https://certs.opera.com/03/ev-oids.xml -# see #967 - - out "$indent"; pr_bold " Certificate Validity (UTC) " - IFS=',' read -r startdate enddate diffseconds days2expire yearstart < <(determine_dates_certificate "$cert_txt") - - # We adjust the thresholds by %50 for LE certificates, relaxing warnings for those certificates. - # . instead of \' because it does not break syntax highlighting in vim - if [[ "$issuer_O" =~ ^Let.s\ Encrypt ]] ; then - days2warn2=$((days2warn2 / 2)) - days2warn1=$((days2warn1 / 2)) - fi - - debugme echo -n "(diffseconds: $diffseconds)" - if ! [[ "$($OPENSSL x509 -checkend 1 2>>$ERRFILE <<< "$hostcert")" =~ \ not\ ]]; then - pr_svrty_critical "expired" - expfinding="expired" - expok="CRITICAL" - set_grade_cap "T" "Certificate expired" - else - # low threshold first - if [[ "$($OPENSSL x509 -checkend $((secsaday*days2warn2)) 2>>$ERRFILE <<< "$hostcert")" =~ \ not\ ]]; then - # high threshold - if [[ "$($OPENSSL x509 -checkend $((secsaday*days2warn1)) 2>>$ERRFILE <<< "$hostcert")" =~ \ not\ ]]; then - pr_svrty_good "$days2expire >= $days2warn1 days" - expfinding+="$days2expire >= $days2warn1 days" - else - pr_svrty_medium "expires < $days2warn1 days ($days2expire)" - expfinding+="expires < $days2warn1 days ($days2expire)" - expok="MEDIUM" - fi - else - pr_svrty_high "expires < $days2warn2 days ($days2expire)" - expfinding+="expires < $days2warn2 days ($days2expire)" - expok="HIGH" - fi - fi - outln " ($startdate --> $enddate)" - fileout "cert_expirationStatus${json_postfix}" "$expok" "$expfinding" - fileout "cert_notBefore${json_postfix}" "INFO" "$startdate" # we assume that the certificate has no start time in the future - fileout "cert_notAfter${json_postfix}" "$expok" "$enddate" # They are in UTC - - # Internal certificates or those from appliances often have too high validity periods. - # We check for ~10 years and >~ 5 years - if [[ $diffseconds -ge $((secsaday*365*10)) ]]; then - out "$spaces" - prln_svrty_high ">= 10 years is way too long" - fileout "cert_extlifeSpan${json_postfix}" "HIGH" "$((diffseconds / secsaday)) days" - elif [[ $diffseconds -ge $((secsaday*365*5)) ]]; then - out "$spaces" - prln_svrty_medium ">= 5 years is too long" - fileout "cert_extlifeSpan${json_postfix}" "MEDIUM" "$((diffseconds / secsaday)) days" - elif [[ $diffseconds -ge $((secsaday*398 + 1)) ]]; then - # Also "official" certificates issued from september 1st 2020 (1598918400) aren't supposed - # to be valid longer than 398 days which is 34387200 in epoch seconds - gt_398=true - if "$HAS_OPENBSDDATE"; then - if [[ 20200901 -le ${yearstart//-/} ]]; then - gt_398warn=true - fi - elif [[ $(parse_date "$startdate" "+%s" $'%F %H:%M') -ge 1598918400 ]]; then - gt_398warn=true - fi - # Now, the verdict, depending on the issuing date - out "$spaces" - if "$gt_398warn" && "$gt_398"; then - prln_svrty_medium "> 398 days issued after 2020/09/01 is too long" - fileout "cert_extlifeSpan${json_postfix}" "MEDIUM" "$((diffseconds / secsaday)) > 398 days" - elif "$gt_398"; then - outln ">= 398 days certificate life time but issued before 2020/09/01" - fileout "cert_extlifeSpan${json_postfix}" "INFO" "$((diffseconds / secsaday)) =< 398 days" - fi - elif [[ $diffseconds -ge $((secsaday*825 + 1)) ]]; then - # Also "official" certificates issued from March 1st, 2018 (1517353200) aren't supposed - # to be valid longer than 825 days which is 1517353200 in epoch seconds - gt_825=true - if "$HAS_OPENBSDDATE"; then - if [[ 20180301 -le ${yearstart//-/} ]]; then - gt_825warn=true - fi - elif [[ $(parse_date "$startdate" "+%s" $'%F %H:%M') -ge 1517353200 ]]; then - gt_825warn=true - fi - # Now, the verdict, depending on the issuing date - out "$spaces" - if "$gt_825warn" && "$gt_825"; then - prln_svrty_medium "> 825 days issued after 2018/03/01 is too long" - fileout "cert_extlifeSpan${json_postfix}" "MEDIUM" "$((diffseconds / secsaday)) > 825 days" - elif "$gt_825"; then - outln ">= 825 days certificate life time but issued before 2018/03/01" - fileout "cert_extlifeSpan${json_postfix}" "INFO" "$((diffseconds / secsaday)) =< 825 days" - fi - else - # All is fine with validity period - # We ignore for now certificates < 2018/03/01. On the screen we only show debug info - debugme echo "${spaces}DEBUG: all is fine with total certificate life time" - fileout "cert_extlifeSpan${json_postfix}" "OK" "certificate has no extended life time according to browser forum" - fi - - out "$indent"; pr_bold " ETS/\"eTLS\"" - out ", visibility info " - jsonID="cert_eTLS" - etsi_ets_visibility_info "${jsonID}${json_postfix}" "$spaces" "$hostcert" "$cert_txt" - # *Currently* this is even listed as a vulnerability (CWE-310, CVE-2019-919), see - # https://nvd.nist.gov/vuln/detail/CVE-2019-9191, https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9191 - # For now we leave this here. We may want to change that later or add infos to other sections (FS & vulnerability) - - if "$PHONE_OUT"; then - out "$indent"; pr_bold " In pwnedkeys.com DB " - check_pwnedkeys "$HOSTCERT" "$cert_key_algo" "$cert_keysize" - case "$?" in - 0) outln "not checked"; fileout "pwnedkeys${json_postfix}" "INFO" "not checked" ;; - 1) outln "not in database"; fileout "pwnedkeys${json_postfix}" "INFO" "not in database" ;; - 2) pr_svrty_critical "NOT ok --"; outln " key appears in database"; fileout "pwnedkeys${json_postfix}" "CRITICAL" "private key is known" ;; - 7) prln_warning "error querying https://v1.pwnedkeys.com"; fileout "pwnedkeys${json_postfix}" "WARN" "connection error" ;; - esac - fi - - out "$indent"; pr_bold " Certificate Revocation List " - jsonID="cert_crlDistributionPoints" - # ~ get next 50 lines after pattern , strip until Signature Algorithm and retrieve URIs - crl="$(awk '/X509v3 CRL Distribution/{i=50} i&&i--' <<< "$cert_txt" | awk '/^$|^.*Name.*$|^.*Reasons.*$|^.*CRL Issuer.*$/,/^ [a-zA-Z0-9]+|^ Signature Algorithm:/' | awk -F'URI:' '/URI/ { print $2 }')" - if [[ -z "$crl" ]] ; then - fileout "${jsonID}${json_postfix}" "INFO" "--" - outln "--" - else - if [[ $(count_lines "$crl") -eq 1 ]]; then - out "$crl" - if [[ "$expfinding" != "expired" ]]; then - check_revocation_crl "$crl" "cert_crlRevoked${json_postfix}" - ret=$((ret +$?)) - fi - outln - else # more than one CRL - first_crl=true - while read -r line; do - if "$first_crl"; then - first_crl=false - else - out "$spaces" - fi - out "$line" - if [[ "$expfinding" != expired ]]; then - check_revocation_crl "$line" "cert_crlRevoked${json_postfix}" - ret=$((ret +$?)) - fi - outln - done <<< "$crl" - fi - fileout "${jsonID}${json_postfix}" "INFO" "$crl" - fi - - out "$indent"; pr_bold " OCSP URI " - jsonID="cert_ocspURL" - ocsp_uri="$($OPENSSL x509 -noout -ocsp_uri 2>>$ERRFILE <<< "$hostcert")" - if [[ -z "$ocsp_uri" ]]; then - outln "--" - fileout "${jsonID}${json_postfix}" "INFO" "--" - else - if [[ $(count_lines "$ocsp_uri") -eq 1 ]]; then - out "$ocsp_uri" - if [[ "$expfinding" != expired ]]; then - check_revocation_ocsp "$ocsp_uri" "" "cert_ocspRevoked${json_postfix}" - fi - ret=$((ret +$?)) - outln - else - first_ocsp=true - while read -r line; do - if "$first_ocsp"; then - first_ocsp=false - else - out "$spaces" - fi - out "$line" - if [[ "$expfinding" != expired ]]; then - check_revocation_ocsp "$line" "" "cert_ocspRevoked${json_postfix}" - ret=$((ret +$?)) - fi - outln - done <<< "$ocsp_uri" - fi - fileout "${jsonID}${json_postfix}" "INFO" "$ocsp_uri" - fi - if [[ -z "$ocsp_uri" ]] && [[ -z "$crl" ]]; then - out "$spaces" - pr_svrty_high "NOT ok --" - outln " neither CRL nor OCSP URI provided" - fileout "cert_revocation${json_postfix}" "HIGH" "Neither CRL nor OCSP URI provided" - fi - - out "$indent"; pr_bold " OCSP stapling " - jsonID="OCSP_stapling" - if grep -a "OCSP response" <<< "$ocsp_response" | grep -q "no response sent" ; then - if [[ -n "$ocsp_uri" ]]; then - pr_svrty_low "not offered" - fileout "${jsonID}${json_postfix}" "LOW" "not offered" - else - out "not offered" - fileout "${jsonID}${json_postfix}" "INFO" "not offered" - fi - else - if grep -a "OCSP Response Status" <<< "$ocsp_response_status" | grep -q successful; then - pr_svrty_good "offered" - fileout "${jsonID}${json_postfix}" "OK" "offered" - provides_stapling=true - check_revocation_ocsp "" "$ocsp_response_binary" "cert_ocspRevoked${json_postfix}" - elif [[ "$ocsp_response" =~ Responder\ Error: ]]; then - response="$(awk '/Responder Error:/ { print $3 }' <<< "$ocsp_response")" - pr_warning "stapled OCSP response contained an error response from OCSP responder: $response" - fileout "${jsonID}${json_postfix}" "WARN" "stapled OCSP response contained an error response from OCSP responder: $response" - else - if $GOST_STATUS_PROBLEM; then - pr_warning "(GOST servers make problems here, sorry)" - fileout "${jsonID}${json_postfix}" "WARN" "(The GOST server made a problem here, sorry)" - ((ret++)) - else - out "(response status unknown)" - fileout "${jsonID}${json_postfix}" "OK" " not sure what's going on here, '$ocsp_response'" - debugme grep -a -A20 -B2 "OCSP response" <<< "$ocsp_response" - ((ret++)) - fi - fi - fi - outln - - out "$indent"; pr_bold " OCSP must staple extension "; - must_staple "$json_postfix" "$provides_stapling" "$cert_txt" - - out "$indent"; pr_bold " DNS CAA RR"; out " (experimental) " - jsonID="DNS_CAArecord" - caa_node="$NODE" - caa="" - while [[ -z "$caa" ]] && [[ -n "$caa_node" ]]; do - caa="$(get_caa_rr_record $caa_node)" - tmp=${PIPESTATUS[@]} - [[ $DEBUG -ge 4 ]] && echo "get_caa_rr_record: $tmp" - [[ $caa_node =~ '.'$ ]] || caa_node+="." - caa_node=${caa_node#*.} - done - if [[ -n "$caa" ]]; then - pr_svrty_good "available"; out " - please check for match with \"Issuer\" below" - if [[ $(count_lines "$caa") -eq 1 ]]; then - out ": " - else - outln; out "$spaces" - fi - while read caa; do - if [[ -n "$caa" ]]; then - all_caa+="$caa, " - fi - done <<< "$caa" - all_caa=${all_caa%, } # strip trailing comma - pr_italic "$(out_row_aligned_max_width "$all_caa" "$indent " $TERM_WIDTH)" - fileout "${jsonID}${json_postfix}" "OK" "$all_caa" - elif [[ -n "$NODNS" ]]; then - out "(instructed to minimize DNS queries)" - fileout "${jsonID}${json_postfix}" "INFO" "check skipped as instructed" - elif "$DNS_VIA_PROXY"; then - out "(instructed to use the proxy for DNS only)" - fileout "${jsonID}${json_postfix}" "INFO" "check skipped as instructed (proxy)" - else - pr_svrty_low "not offered" - fileout "${jsonID}${json_postfix}" "LOW" "--" - fi - outln - - out "$indent"; pr_bold " Certificate Transparency "; - jsonID="certificate_transparency" - if [[ "$ct" =~ extension ]]; then - pr_svrty_good "yes"; outln " ($ct)" - fileout "${jsonID}${json_postfix}" "OK" "yes ($ct)" - else - outln "$ct" - fileout "${jsonID}${json_postfix}" "INFO" "$ct" - fi - - out "$indent"; pr_bold " Certificates provided" - certificates_provided="$(grep -ace '-----BEGIN CERTIFICATE-----' <<< "$intermediates")" - ((certificates_provided++)) # plus host certificate - out " $certificates_provided" - fileout "certs_countServer${json_postfix}" "INFO" "${certificates_provided}" - if "$certificate_list_ordering_problem"; then - prln_svrty_low " (certificate list ordering problem)" - fileout "certs_list_ordering_problem${json_postfix}" "LOW" "yes" - else - fileout "certs_list_ordering_problem${json_postfix}" "INFO" "no" - outln - fi - - out "$indent"; pr_bold " Issuer " - jsonID="cert_caIssuers" - - if [[ "$issuer_O" == issuer= ]] || [[ "$issuer_O" == issuer=\ ]] || [[ "$issuer_CN" == "$cn" ]]; then - prln_svrty_critical "self-signed (NOT ok)" - fileout "${jsonID}${json_postfix}" "CRITICAL" "selfsigned" - set_grade_cap "T" "Self-signed certificate" - else - issuerfinding="$issuer_CN" - pr_italic "$issuer_CN" - if [[ -z "$issuer_O" ]] && [[ -n "$issuer_DC" ]]; then - for san in $issuer_DC; do - if [[ -z "$issuer_O" ]]; then - issuer_O="${san}" - else - issuer_O="${san}.${issuer_O}" - fi - done - fi - if [[ -n "$issuer_O" ]]; then - issuerfinding+=" (" - out " (" - issuerfinding+="$issuer_O" - pr_italic "$issuer_O" - if [[ -n "$issuer_C" ]]; then - issuerfinding+=" from " - out " from " - issuerfinding+="$issuer_C" - pr_italic "$issuer_C" - fi - issuerfinding+=")" - out ")" - fi - outln - fileout "${jsonID}${json_postfix}" "INFO" "$issuerfinding" - fi - - -# Now we take care of the intermediate certificates. We basically (should) have them on disk -# as "intermediatecerts.pem" (which could be split into intermediatecert1.crt, intermediatecert2.crt, ..) -# However we do this in RAM which is better as it was passed to this function. -# We should keep in mind though this is somewhat redundant code. We do similar stuff elsewhere, -# e.g. in extract_certificates() and run_hpkp() but don't keep the certificates - - # Store all of the text output of the intermediate certificates in an array so that they can - # be used later (e.g., to check their expiration dates). - for (( i=1; i < certificates_provided; i++ )); do - [[ "$intermediates" =~ \-\-\-\-\-BEGIN\ CERTIFICATE\-\-\-\-\- ]] || break - intermediates="${intermediates#*-----BEGIN CERTIFICATE-----}" - cert="${intermediates%%-----END CERTIFICATE-----*}" - intermediates="${intermediates#${cert}-----END CERTIFICATE-----}" - cert="-----BEGIN CERTIFICATE-----${cert}-----END CERTIFICATE-----" - - fileout "intermediate_cert <#${i}>${json_postfix}" "INFO" "$(pem_to_one_line "$cert")" - fileout "intermediate_cert_fingerprintSHA256 <#${i}>${json_postfix}" "INFO" "$(determine_cert_fingerprint_serial "$cert" "-fingerprint -sha256")" - - intermediate_certs_txt[i]="$($OPENSSL x509 -text -noout 2>/dev/null <<< "$cert")" - - # We don't need every value here. For the sake of being consistent here we add the rest - IFS=',' read -r startdate enddate diffseconds days2expire yearstart < <(determine_dates_certificate "${intermediate_certs_txt[i]}") - fileout "intermediate_cert_notBefore <#${i}>${json_postfix}" "INFO" "$startdate" - - if $first; then - out "$indent"; pr_bold " Intermediate cert validity " - first=false - else - out "$indent$spaces" - fi - out "#${i}: " - if ! [[ "$($OPENSSL x509 -checkend 1 2>>$ERRFILE <<< "$cert")" =~ \ not\ ]]; then - cn_finding="expired!" - pr_svrty_critical "$cn_finding" - expok="CRITICAL" - elif ! [[ "$($OPENSSL x509 -checkend $((secsaday*20)) 2>>$ERRFILE <<< "$cert")" =~ \ not\ ]]; then - cn_finding="expires <= 20 days" - pr_svrty_high "$cn_finding" - expok="HIGH" - elif ! [[ "$($OPENSSL x509 -checkend $((secsaday*40)) 2>>$ERRFILE <<< "$cert")" =~ \ not\ ]]; then - cn_finding="expires <= 40 days" - pr_svrty_medium "$cn_finding" - expok="MEDIUM" - else - cn_finding="ok > 40 days" - pr_svrty_good "$cn_finding" - expok="OK" - fi - out " ($enddate). " - cn="$(awk -F= '/Subject:.*CN/ { print $NF }' <<< "${intermediate_certs_txt[i]}")" - issuer_CN="$(awk -F= '/Issuer:.*CN/ { print $NF }' <<< "${intermediate_certs_txt[i]}")" - pr_italic "$(strip_leading_space "$cn")"; out " <-- "; prln_italic "$(strip_leading_space "$issuer_CN")" - fileout "intermediate_cert_notAfter <#${i}>${json_postfix}" "$expok" "$enddate" - fileout "intermediate_cert_expiration <#${i}>${json_postfix}" "$expok" "$cn_finding" - fileout "intermediate_cert_chain <#${i}>${json_postfix}" "INFO" "$cn <-- $issuer_CN" - done - - # Courtesy Hanno Böck (see https://github.com/hannob/badocspcert) - out "$indent"; pr_bold " Intermediate Bad OCSP" - out " (exp.) " - jsonID="intermediate_cert_badOCSP" - - for (( i=1; i < certificates_provided; i++ )); do - cert_ext_keyusage="$(awk '/X509v3 Extended Key Usage:/ { getline; print $0 }' <<< "${intermediate_certs_txt[i]}")" - [[ "$cert_ext_keyusage" =~ OCSP\ Signing ]] && badocsp=0 && break - done - if [[ $badocsp -eq 0 ]]; then - prln_svrty_medium "NOT ok" - fileout "${jsonID}${json_postfix}" "MEDIUM" "NOT ok is intermediate certificate ${i}" - else - prln_svrty_good "Ok" - fileout "${jsonID}${json_postfix}" "OK" "intermediate certificate(s) is/are ok" - fi - - outln - return $ret -} - -run_server_defaults() { - local ciph newhostcert sni - local match_found - local sessticket_lifetime_hint="" sessticket_proto="" lifetime unit - local -i i n - local -i certs_found=0 - local -i ret=0 - local -a previous_hostcert previous_hostcert_txt previous_hostcert_type - local -a previous_hostcert_issuer previous_intermediates previous_ordering_problem keysize tested_cipher - local -a ocsp_response_binary ocsp_response ocsp_response_status sni_used tls_version ct - local -a ciphers_to_test certificate_type - local -a -i success - local cn_nosni cn_sni sans_nosni sans_sni san tls_extensions client_auth_ca - local using_sockets=true - - "$SSL_NATIVE" && using_sockets=false - - # Try each public key type once: - # ciphers_to_test[1]: cipher suites using certificates with RSA signature public keys - # ciphers_to_test[2]: cipher suites using certificates with RSA key encipherment public keys - # ciphers_to_test[3]: cipher suites using certificates with DSA signature public keys - # ciphers_to_test[4]: cipher suites using certificates with DH key agreement public keys - # ciphers_to_test[5]: cipher suites using certificates with ECDH key agreement public keys - # ciphers_to_test[6]: cipher suites using certificates with ECDSA signature public keys - # ciphers_to_test[7]: cipher suites using certificates with GOST R 34.10 (either 2001 or 94) public keys - ciphers_to_test[1]="aRSA:eRSA" - ciphers_to_test[2]="" - ciphers_to_test[3]="aDSS:aDH:aECDH:aECDSA:aGOST" - ciphers_to_test[4]="" - ciphers_to_test[5]="" - ciphers_to_test[6]="" - ciphers_to_test[7]="" - ciphers_to_test[8]="tls1_3_RSA" - ciphers_to_test[9]="tls1_3_ECDSA" - ciphers_to_test[10]="tls1_3_EdDSA" - certificate_type[1]="" ; certificate_type[2]="" - certificate_type[3]=""; certificate_type[4]="" - certificate_type[5]="" ; certificate_type[6]="" - certificate_type[7]="" ; certificate_type[8]="RSASig" - certificate_type[9]="ECDSA" ; certificate_type[10]="EdDSA" - - for (( n=1; n <= 17 ; n++ )); do - # Some servers use a different certificate if the ClientHello - # specifies TLSv1.1 and doesn't include a server name extension. - # So, for each public key type for which a certificate was found, - # try again, but only with TLSv1.1 and without SNI. - if [[ $n -ne 1 ]] && [[ "$OPTIMAL_PROTO" == -ssl2 ]]; then - ciphers_to_test[n]="" - elif [[ $n -ge 11 ]]; then - ciphers_to_test[n]="" - [[ ${success[n-10]} -eq 0 ]] && [[ $(has_server_protocol "tls1_1") -ne 1 ]] && \ - ciphers_to_test[n]="${ciphers_to_test[n-10]}" && certificate_type[n]="${certificate_type[n-10]}" - fi - - if [[ -n "${ciphers_to_test[n]}" ]]; then - if [[ $n -ge 11 ]]; then - sni="$SNI" - SNI="" - get_server_certificate "${ciphers_to_test[n]}" "tls1_1" - success[n]=$? - SNI="$sni" - else - get_server_certificate "${ciphers_to_test[n]}" - success[n]=$? - fi - if [[ ${success[n]} -eq 0 ]] && [[ -s "$HOSTCERT" ]]; then - [[ $n -ge 11 ]] && [[ ! -e $HOSTCERT.nosni ]] && cp $HOSTCERT $HOSTCERT.nosni - cp "$TEMPDIR/$NODEIP.get_server_certificate.txt" $TMPFILE - >$ERRFILE - if [[ -z "$sessticket_lifetime_hint" ]]; then - sessticket_lifetime_hint=$(awk '/session ticket life/ { if (!found) print; found=1 }' $TMPFILE) - sessticket_proto="$(get_protocol "$TMPFILE")" - fi - - if [[ $n -le 7 ]]; then - ciph="$(get_cipher $TMPFILE)" - if [[ "$ciph" != TLS_* ]] && [[ "$ciph" != SSL_* ]]; then - ciph="$(openssl2rfc "$ciph")" - fi - if [[ "$ciph" == TLS_DHE_RSA_* ]] || [[ "$ciph" == TLS_ECDHE_RSA_* ]] || [[ "$ciph" == TLS_CECPQ1_RSA_* ]]; then - certificate_type[n]="RSASig" - if [[ -z "${ciphers_to_test[n+1]}" ]]; then - ciphers_to_test[n+1]="${ciphers_to_test[n]/aRSA/}" - ciphers_to_test[n+1]="${ciphers_to_test[n+1]/::/:}" - [[ "${ciphers_to_test[n+1]:0:1}" == : ]] && ciphers_to_test[n+1]="${ciphers_to_test[n+1]:1}" - fi - ciphers_to_test[n]="aRSA" - elif [[ "$ciph" == TLS_RSA_* ]] || [[ "$ciph" == SSL_* ]] || [[ "$ciph" == TLS_GOST*_RSA_* ]]; then - certificate_type[n]="RSAKMK" - if [[ -z "${ciphers_to_test[n+1]}" ]]; then - ciphers_to_test[n+1]="${ciphers_to_test[n]/eRSA/}" - ciphers_to_test[n+1]="${ciphers_to_test[n+1]/::/:}" - [[ "${ciphers_to_test[n+1]:0:1}" == : ]] && ciphers_to_test[n+1]="${ciphers_to_test[n+1]:1}" - fi - ciphers_to_test[n]="eRSA" - elif [[ "$ciph" == TLS_DHE_DSS_* ]]; then - certificate_type[n]="DSA" - if [[ -z "${ciphers_to_test[n+1]}" ]]; then - ciphers_to_test[n+1]="${ciphers_to_test[n]/aDSS/}" - ciphers_to_test[n+1]="${ciphers_to_test[n+1]/::/:}" - [[ "${ciphers_to_test[n+1]:0:1}" == : ]] && ciphers_to_test[n+1]="${ciphers_to_test[n+1]:1}" - fi - ciphers_to_test[n]="aDSS" - elif [[ "$ciph" == TLS_DH_* ]]; then - certificate_type[n]="DH" - if [[ -z "${ciphers_to_test[n+1]}" ]]; then - ciphers_to_test[n+1]="${ciphers_to_test[n]/aDH/}" - ciphers_to_test[n+1]="${ciphers_to_test[n+1]/::/:}" - [[ "${ciphers_to_test[n+1]:0:1}" == : ]] && ciphers_to_test[n+1]="${ciphers_to_test[n+1]:1}" - fi - ciphers_to_test[n]="aDH" - elif [[ "$ciph" == TLS_ECDH_* ]]; then - certificate_type[n]="ECDH" - if [[ -z "${ciphers_to_test[n+1]}" ]]; then - ciphers_to_test[n+1]="${ciphers_to_test[n]/aECDH/}" - ciphers_to_test[n+1]="${ciphers_to_test[n+1]/::/:}" - [[ "${ciphers_to_test[n+1]:0:1}" == : ]] && ciphers_to_test[n+1]="${ciphers_to_test[n+1]:1}" - fi - ciphers_to_test[n]="aECDH" - elif [[ "$ciph" == TLS_ECDHE_ECDSA_* ]] || [[ "$ciph" == TLS_CECPQ1_ECDSA_* ]]; then - certificate_type[n]="ECDSA" - if [[ -z "${ciphers_to_test[n+1]}" ]]; then - ciphers_to_test[n+1]="${ciphers_to_test[n]/aECDSA/}" - ciphers_to_test[n+1]="${ciphers_to_test[n+1]/::/:}" - [[ "${ciphers_to_test[n+1]:0:1}" == : ]] && ciphers_to_test[n+1]="${ciphers_to_test[n+1]:1}" - fi - ciphers_to_test[n]="aECDSA" - elif [[ "$ciph" == TLS_GOST* ]]; then - certificate_type[n]="GOST" - if [[ -z "${ciphers_to_test[n+1]}" ]]; then - ciphers_to_test[n+1]="${ciphers_to_test[n]/aGOST/}" - ciphers_to_test[n+1]="${ciphers_to_test[n+1]/::/:}" - [[ "${ciphers_to_test[n+1]:0:1}" == : ]] && ciphers_to_test[n+1]="${ciphers_to_test[n+1]:1}" - fi - ciphers_to_test[n]="aGOST" - fi - fi - # check whether the host's certificate has been seen before - match_found=false - i=1 - newhostcert=$(cat $HOSTCERT) - while [[ $i -le $certs_found ]]; do - if [[ "$newhostcert" == "${previous_hostcert[i]}" ]]; then - match_found=true - break; - fi - i=$((i + 1)) - done - if ! "$match_found" && [[ $n -ge 11 ]] && [[ $certs_found -ne 0 ]]; then - # A new certificate was found using TLSv1.1 without SNI. - # Check to see if the new certificate should be displayed. - # It should be displayed if it is either a match for the - # $NODE being tested or if it has the same subject - # (CN and SAN) as other certificates for this host. - compare_server_name_to_cert "$HOSTCERT" - [[ $? -ne 0 ]] && success[n]=0 || success[n]=1 - - if [[ ${success[n]} -ne 0 ]]; then - cn_nosni="$(toupper "$(get_cn_from_cert $HOSTCERT)")" - sans_nosni="$(toupper "$(get_san_dns_from_cert "$HOSTCERT")")" - - echo "${previous_hostcert[1]}" > $HOSTCERT - cn_sni="$(toupper "$(get_cn_from_cert $HOSTCERT)")" - - # FIXME: Not sure what the matching rule should be. At - # the moment, the no SNI certificate is considered a - # match if the CNs are the same and the SANs (if - # present) contain at least one DNS name in common. - if [[ "$cn_nosni" == "$cn_sni" ]]; then - sans_sni="$(toupper "$(get_san_dns_from_cert "$HOSTCERT")")" - if [[ "$sans_nosni" == "$sans_sni" ]]; then - success[n]=0 - else - while read -r san; do - [[ -n "$san" ]] && [[ " $sans_sni " =~ \ $san\ ]] && success[n]=0 && break - done <<< "$sans_nosni" - fi - fi - fi - # If the certificate found for TLSv1.1 w/o SNI appears to - # be for a different host, then set match_found to true so - # that the new certificate will not be included in the output. - [[ ${success[n]} -ne 0 ]] && match_found=true - fi - if ! "$match_found"; then - certs_found=$(( certs_found + 1)) - tested_cipher[certs_found]=${ciphers_to_test[n]} - keysize[certs_found]=$(awk '/Server public key/ { print $(NF-1) }' $TMPFILE) - # If an OCSP response was sent, then get the full - # response so that certificate_info() can determine - # whether it includes a certificate transparency extension. - ocsp_response_binary[certs_found]="$STAPLED_OCSP_RESPONSE" - if grep -a "OCSP response:" $TMPFILE | grep -q "no response sent"; then - ocsp_response[certs_found]="$(grep -a "OCSP response" $TMPFILE)" - else - ocsp_response[certs_found]="$(awk -v n=2 '/OCSP response:/ {start=1; inc=2} /======================================/ { if (start) {inc--} } inc' $TMPFILE)" - fi - ocsp_response_status[certs_found]=$(grep -a "OCSP Response Status" $TMPFILE) - previous_hostcert[certs_found]=$newhostcert - previous_hostcert_txt[certs_found]="$($OPENSSL x509 -noout -text 2>>$ERRFILE <<< "$newhostcert")" - previous_intermediates[certs_found]=$(cat $TEMPDIR/intermediatecerts.pem) - previous_hostcert_issuer[certs_found]="" - [[ -n "${previous_intermediates[certs_found]}" ]] && [[ -r $TEMPDIR/hostcert_issuer.pem ]] && \ - previous_hostcert_issuer[certs_found]=$(cat $TEMPDIR/hostcert_issuer.pem) - previous_ordering_problem[certs_found]=$CERTIFICATE_LIST_ORDERING_PROBLEM - [[ $n -ge 11 ]] && sni_used[certs_found]="" || sni_used[certs_found]="$SNI" - tls_version[certs_found]="$DETECTED_TLS_VERSION" - previous_hostcert_type[certs_found]=" ${certificate_type[n]}" - if [[ $DEBUG -ge 1 ]]; then - echo "${previous_hostcert[certs_found]}" > $TEMPDIR/host_certificate_$certs_found.pem - echo "${previous_hostcert_txt[certs_found]}" > $TEMPDIR/host_certificate_$certs_found.txt - fi - else - previous_hostcert_type[i]+=" ${certificate_type[n]}" - fi - fi - fi - done - - determine_tls_extensions - if [[ $? -eq 0 ]] && [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then - cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE - >$ERRFILE - if [[ -z "$sessticket_lifetime_hint" ]]; then - sessticket_lifetime_hint=$(awk '/session ticket lifetime/ { if (!found) print; found=1 }' $TMPFILE) - sessticket_proto="$(get_protocol "$TMPFILE")" - fi - fi - TLS13_CERT_COMPRESS_METHODS="" - "$using_sockets" && determine_cert_compression - [[ -n "$TLS13_CERT_COMPRESS_METHODS" ]] && [[ "$TLS13_CERT_COMPRESS_METHODS" != "none" ]] && \ - extract_new_tls_extensions "$TEMPDIR/$NODEIP.determine_cert_compression.txt" - - if "$using_sockets" && ! "$TLS13_ONLY" && [[ -z "$sessticket_lifetime_hint" ]] && [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then - if "$HAS_TLS13" && [[ -z "$OPTIMAL_PROTO" || "$OPTIMAL_PROTO" == -tls1_3 ]] ; then - # If a session ticket were sent in response to a TLSv1.3 ClientHello, then a session ticket - # would have been found by get_server_certificate(). So, try again with a TLSv1.2 ClientHello. - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -no_tls1_3 -connect $NODEIP:$PORT $PROXY $SNI") $ERRFILE >$TMPFILE - else - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS "$OPTIMAL_PROTO" -connect $NODEIP:$PORT $PROXY $SNI") $ERRFILE >$TMPFILE - fi - if sclient_connect_successful $? $TMPFILE; then - sessticket_lifetime_hint=$(awk '/session ticket lifetime/ { if (!found) print; found=1 }' $TMPFILE) - sessticket_proto="$(get_protocol "$TMPFILE")" - fi - fi - [[ -z "$sessticket_lifetime_hint" ]] && TLS_TICKETS=false || TLS_TICKETS=true - - debugme echo "# certificates found $certs_found" - # Now that all of the server's certificates have been found, determine for - # each certificate whether certificate transparency information is provided. - for (( i=1; i <= certs_found; i++ )); do - certificate_transparency "${previous_hostcert_txt[i]}" "${ocsp_response[i]}" "$certs_found" "${tested_cipher[i]}" "${sni_used[i]}" "${tls_version[i]}" - ct[i]="$CERTIFICATE_TRANSPARENCY_SOURCE" - # If certificate_transparency() called tls_sockets() and found a "signed certificate timestamps" extension, - # then add it to $TLS_EXTENSIONS, since it may not have been found by determine_tls_extensions(). - [[ $certs_found -gt 1 ]] && [[ "${ct[i]}" == TLS\ extension ]] && extract_new_tls_extensions "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" - done - - outln - pr_headlineln " Testing server defaults (Server Hello) " - outln - - pr_bold " TLS extensions (standard) " - if [[ -z "$TLS_EXTENSIONS" ]]; then - outln "(none)" - fileout "TLS_extensions" "INFO" "(none)" - else -#FIXME: we rather want to have the chance to print each ext in italics or another format. -# Atm is a string of quoted strings -- that needs to be fixed at the root then - # out_row_aligned_max_width() places line breaks at space characters. - # So, in order to prevent the text for an extension from being broken - # across lines, temporarily replace space characters within the text - # of an extension with "}", and then convert the "}" back to space in - # the output of out_row_aligned_max_width(). - tls_extensions="${TLS_EXTENSIONS// /{}" - tls_extensions="${tls_extensions//\"{\"/\" \"}" - tls_extensions="$(out_row_aligned_max_width "$tls_extensions" " " $TERM_WIDTH)" - tls_extensions="${tls_extensions//{/ }" - outln "$tls_extensions" - fileout "TLS_extensions" "INFO" "$TLS_EXTENSIONS" - fi - - pr_bold " Session Ticket RFC 5077 hint " - jsonID="TLS_session_ticket" - if [[ -z "$sessticket_lifetime_hint" ]]; then - outln "no -- no lifetime advertised" - fileout "${jsonID}" "INFO" "no -- no lifetime advertised" - # it MAY be given a hint of the lifetime of the ticket, see https://tools.ietf.org/html/rfc5077#section-5.6 . - # Sometimes it just does not -- but it then may also support TLS session tickets reuse - else - lifetime=$(grep -a lifetime <<< "$sessticket_lifetime_hint" | sed 's/[A-Za-z:() ]//g') - unit=$(grep -a lifetime <<< "$sessticket_lifetime_hint" | sed -e 's/^.*'"$lifetime"'//' -e 's/[ ()]//g') - out "$lifetime $unit" - if [[ $((3600 * 24)) -lt $lifetime ]]; then - prln_svrty_low " but: FS requires session ticket keys to be rotated < daily !" - fileout "$jsonID" "LOW" "valid for $lifetime $unit (>daily)" - else - outln ", session tickets keys seems to be rotated < daily" - fileout "$jsonID" "INFO" "valid for $lifetime $unit only (>$ERRFILE $HOSTCERT.nosni - fi - else - >$HOSTCERT.nosni - fi - mv $HOSTCERT.save $HOSTCERT - SNI="$sni" - else - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $OPTIMAL_PROTO") 2>>$ERRFILE $HOSTCERT.nosni - fi - elif [[ $certs_found -eq 0 ]] && [[ -s "$HOSTCERT" ]]; then - outln - generic_nonfatal "Client problem, shouldn't happen: Host certificate found but we can't continue with \"server defaults\"." - elif [[ $certs_found -eq 0 ]]; then - outln - if $TLS13_ONLY; then - generic_nonfatal "Client problem: We need openssl supporting TLS 1.3. We can't continue with \"server defaults\" as we cannot retrieve the certificate. " - else - generic_nonfatal "Client problem: No server certificate could be retrieved. Thus we can't continue with \"server defaults\"." - fi - fi - [[ $DEBUG -ge 1 ]] && [[ -e $HOSTCERT.nosni ]] && $OPENSSL x509 -in $HOSTCERT.nosni -text -noout 2>>$ERRFILE > $HOSTCERT.nosni.txt - - fileout "cert_numbers" "INFO" "$certs_found" - for (( i=1; i <= certs_found; i++ )); do - echo "${previous_hostcert[i]}" > $HOSTCERT - echo "${previous_intermediates[i]}" > $TEMPDIR/intermediatecerts.pem - echo "${previous_hostcert_issuer[i]}" > $TEMPDIR/hostcert_issuer.pem - certificate_info "$i" "$certs_found" "${previous_hostcert_txt[i]}" "${previous_intermediates[i]}" \ - "${tested_cipher[i]}" "${keysize[i]}" "${previous_hostcert_type[i]}" \ - "${ocsp_response_binary[i]}" "${ocsp_response[i]}" \ - "${ocsp_response_status[i]}" "${sni_used[i]}" "${ct[i]}" \ - "${previous_ordering_problem[i]}" - [[ $? -ne 0 ]] && ((ret++)) - done - return $ret -} - -get_session_ticket_lifetime_from_serverhello() { - awk '/session ticket.*lifetime/ { print $(NF-1) "$1" }' -} - -get_san_dns_from_cert() { - echo "$($OPENSSL x509 -in "$1" -noout -text 2>>$ERRFILE | \ - grep -A2 "Subject Alternative Name" | tr ',' '\n' | grep "DNS:" | \ - sed -e 's/DNS://g' -e 's/ //g')" -} - - -run_fs() { - local -i sclient_success - local fs_offered=false ecdhe_offered=false ffdhe_offered=false - local fs_tls13_offered=false fs_tls12_offered=false - local protos_to_try proto hexc dash fs_cipher sslvers auth mac export curve dhlen - local -a hexcode normalized_hexcode ciph rfc_ciph kx enc ciphers_found sigalg ossl_supported - # generated from 'kEECDH:kEDH:!aNULL:!eNULL:!DES:!3DES:!RC4' with openssl 1.0.2i and openssl 1.1.0 - local fs_cipher_list="DHE-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA:DHE-DSS-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA:DHE-DSS-SEED-SHA:DHE-RSA-AES128-CCM8:DHE-RSA-AES128-CCM:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-CHACHA20-POLY1305-OLD:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-SEED-SHA:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305-OLD:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-RSA-CHACHA20-POLY1305-OLD:ECDHE-RSA-CHACHA20-POLY1305" - local fs_hex_cipher_list="" ciphers_to_test tls13_ciphers_to_test - local ecdhe_cipher_list="" tls13_cipher_list="" ecdhe_cipher_list_hex="" ffdhe_cipher_list_hex="" - local curves_hex=("00,01" "00,02" "00,03" "00,04" "00,05" "00,06" "00,07" "00,08" "00,09" "00,0a" "00,0b" "00,0c" "00,0d" "00,0e" "00,0f" "00,10" "00,11" "00,12" "00,13" "00,14" "00,15" "00,16" "00,17" "00,18" "00,19" "00,1a" "00,1b" "00,1c" "00,1d" "00,1e" "00,1f" "00,20" "00,21") - local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13") - local -a curves_ossl_output=("K-163" "sect163r1" "B-163" "sect193r1" "sect193r2" "K-233" "B-233" "sect239k1" "K-283" "B-283" "K-409" "B-409" "K-571" "B-571" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "P-192" "secp224k1" "P-224" "secp256k1" "P-256" "P-384" "P-521" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13") - local -ai curves_bits=(163 162 163 193 193 232 233 238 281 282 407 409 570 570 161 161 161 192 192 225 224 256 256 384 521 256 384 512 253 448 256 384 512) - # Many curves have been deprecated, and RFC 8446, Appendix B.3.1.4, states - # that these curves MUST NOT be offered in a TLS 1.3 ClientHello. - local -a curves_deprecated=("true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "false" "false" "false" "true" "true" "true" "false" "false" "false" "false" "false") - local -a ffdhe_groups_hex=("01,00" "01,01" "01,02" "01,03" "01,04") - local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") - local -a supported_curve - local -a sigalgs_hex=("01,01" "01,02" "01,03" "02,01" "02,02" "02,03" "03,01" "03,02" "03,03" "04,01" "04,02" "04,03" "04,20" "05,01" "05,02" "05,03" "05,20" "06,01" "06,02" "06,03" "06,20" "07,08" "08,04" "08,05" "08,06" "08,07" "08,08" "08,09" "08,0a" "08,0b" "08,1a" "08,1b" "08,1c") - local -a sigalgs_strings=("RSA+MD5" "DSA+MD5" "ECDSA+MD5" "RSA+SHA1" "DSA+SHA1" "ECDSA+SHA1" "RSA+SHA224" "DSA+SHA224" "ECDSA+SHA224" "RSA+SHA256" "DSA+SHA256" "ECDSA+SHA256" "RSA+SHA256" "RSA+SHA384" "DSA+SHA384" "ECDSA+SHA384" "RSA+SHA384" "RSA+SHA512" "DSA+SHA512" "ECDSA+SHA512" "RSA+SHA512" "SM2+SM3" "RSA-PSS-RSAE+SHA256" "RSA-PSS-RSAE+SHA384" "RSA-PSS-RSAE+SHA512" "Ed25519" "Ed448" "RSA-PSS-PSS+SHA256" "RSA-PSS-PSS+SHA384" "RSA-PSS-PSS+SHA512" "ECDSA+SHA256" "ECDSA+SHA384" "ECDSA+SHA512") - local -a tls13_supported_sigalgs=("false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false") - local -a tls12_supported_sigalgs=("false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false") - local rsa_cipher="" ecdsa_cipher="" dss_cipher="" - local sigalgs_to_test tls12_supported_sigalg_list="" tls13_supported_sigalg_list="" - local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high - local fs_ciphers curves_offered="" curves_to_test temp - local curves_option="" curves_list1="" curves_list2="" - local len1 len2 curve_found sigalg_found - local key_bitstring quality_str - local -i len_dh_p quality - local has_dh_bits="$HAS_DH_BITS" - local using_sockets=true - local jsonID="FS" - - "$SSL_NATIVE" && using_sockets=false - "$FAST" && using_sockets=false - [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false - - outln - pr_headline " Testing robust forward secrecy (FS)"; prln_underline " -- omitting Null Authentication/Encryption, 3DES, RC4 " - if ! "$using_sockets"; then - [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" - if ! "$HAS_DH_BITS" && "$WIDE"; then - [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." - pr_warning " (Your $OPENSSL cannot show DH/ECDH bits)" - fi - outln - fi - - if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - fs_cipher="${TLS_CIPHER_RFC_NAME[i]}" - hexc="${TLS_CIPHER_HEXCODE[i]}" - if [[ "$fs_cipher" == "TLS_DHE_"* || "$fs_cipher" == "TLS_ECDHE_"* || "${hexc:2:2}" == "13" ]] && \ - [[ ! "$fs_cipher" =~ NULL ]] && [[ ! "$fs_cipher" =~ DES ]] && [[ ! "$fs_cipher" =~ RC4 ]] && \ - [[ ! "$fs_cipher" =~ PSK ]] && { "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}"; }; then - fs_hex_cipher_list+=", ${hexc:2:2},${hexc:7:2}" - ciph[nr_supported_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" - rfc_ciph[nr_supported_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" - kx[nr_supported_ciphers]="${TLS_CIPHER_KX[i]}" - enc[nr_supported_ciphers]="${TLS_CIPHER_ENC[i]}" - ciphers_found[nr_supported_ciphers]=false - sigalg[nr_supported_ciphers]="" - ossl_supported[nr_supported_ciphers]="${TLS_CIPHER_OSSL_SUPPORTED[i]}" - hexcode[nr_supported_ciphers]="${hexc:2:2},${hexc:7:2}" - if [[ "${hexc:2:2}" == 00 ]]; then - normalized_hexcode[nr_supported_ciphers]="x${hexc:7:2}" - else - normalized_hexcode[nr_supported_ciphers]="x${hexc:2:2}${hexc:7:2}" - fi - "$using_sockets" && ! "$has_dh_bits" && "$WIDE" && ossl_supported[nr_supported_ciphers]=false - nr_supported_ciphers+=1 - fi - done - else - while read -r hexc dash ciph[nr_supported_ciphers] sslvers kx[nr_supported_ciphers] auth enc[nr_supported_ciphers] mac export; do - ciphers_found[nr_supported_ciphers]=false - if [[ "${hexc:2:2}" == 00 ]]; then - normalized_hexcode[nr_supported_ciphers]="x${hexc:7:2}" - else - normalized_hexcode[nr_supported_ciphers]="x${hexc:2:2}${hexc:7:2}" - fi - sigalg[nr_supported_ciphers]="" - ossl_supported[nr_supported_ciphers]=true - nr_supported_ciphers+=1 - done < <(actually_supported_osslciphers "$fs_cipher_list" "ALL" "-V") - fi - - if [[ $(has_server_protocol "tls1_3") -eq 0 ]]; then - # All TLSv1.3 cipher suites offer robust FS. - sclient_success=0 - elif "$using_sockets"; then - tls_sockets "04" "${fs_hex_cipher_list:2}, 00,ff" - sclient_success=$? - [[ $sclient_success -eq 2 ]] && sclient_success=0 - # Sometimes a TLS 1.3 ClientHello will fail, but a TLS 1.2 ClientHello will succeed. See #2131. - if [[ $sclient_success -ne 0 ]]; then - tls_sockets "03" "${fs_hex_cipher_list:2}, 00,ff" - sclient_success=$? - [[ $sclient_success -eq 2 ]] && sclient_success=0 - fi - else - debugme echo $nr_supported_ciphers - debugme echo $(actually_supported_osslciphers $fs_cipher_list "ALL") - if [[ "$nr_supported_ciphers" -le "$CLIENT_MIN_FS" ]]; then - outln - prln_local_problem "You only have $nr_supported_ciphers FS ciphers on the client side " - fileout "$jsonID" "WARN" "tests skipped as you only have $nr_supported_ciphers FS ciphers on the client site. ($CLIENT_MIN_FS are required)" - return 1 - fi - # By default, OpenSSL 1.1.1 and above only include a few curves in the ClientHello, so in order - # to test all curves, the -curves option must be added. In addition, OpenSSL limits the number of - # curves that can be specified to 28. So, if more than 28 curves are supported, then the curves must - # be tested in batches. - curves_list1="$(strip_trailing_space "$(strip_leading_space "$OSSL_SUPPORTED_CURVES")")" - curves_list1="${curves_list1// / }" - if [[ "$(count_words "$OSSL_SUPPORTED_CURVES")" -gt 28 ]]; then - # Place the first 28 supported curves in curves_list1 and the remainder in curves_list2. - curves_list2="${curves_list1#* * * * * * * * * * * * * * * * * * * * * * * * * * * * }" - curves_list1="${curves_list1%$curves_list2}" - curves_list1="$(strip_trailing_space "$curves_list1")" - curves_list2="${curves_list2// /:}" - fi - curves_list1="${curves_list1// /:}" - $OPENSSL s_client $(s_client_options "-cipher $fs_cipher_list -ciphersuites ALL $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE $TMPFILE "$TEMPDIR/$NODE.$NODEIP.curves_offered.txt" - - # find out what groups are supported. - if "$using_sockets" && { "$fs_tls13_offered" || "$ffdhe_offered"; }; then - nr_curves=0 - for curve in "${ffdhe_groups_output[@]}"; do - supported_curve[nr_curves]=false - [[ "$DH_GROUP_OFFERED" =~ $curve ]] && supported_curve[nr_curves]=true - nr_curves+=1 - done - protos_to_try="" - "$fs_tls13_offered" && protos_to_try="04" - if "$ffdhe_offered"; then - if "$fs_tls13_offered"; then - protos_to_try="04 03" - else - protos_to_try="03" - fi - fi - curve_found="" - for proto in $protos_to_try; do - while true; do - curves_to_test="" - for (( i=0; i < nr_curves; i++ )); do - ! "${supported_curve[i]}" && curves_to_test+=", ${ffdhe_groups_hex[i]}" - done - [[ -z "$curves_to_test" ]] && break - len1=$(printf "%02x" "$((2*${#curves_to_test}/7))") - len2=$(printf "%02x" "$((2*${#curves_to_test}/7+2))") - tls_sockets "$proto" "${ffdhe_cipher_list_hex:2}, 00,ff" "ephemeralkey" "00, 0a, 00, $len2, 00, $len1, ${curves_to_test:2}" - sclient_success=$? - [[ $sclient_success -ne 0 ]] && [[ $sclient_success -ne 2 ]] && break - temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - curve_found="${temp#*, }" - curve_found="${curve_found%%,*}" - if [[ "$proto" == "03" ]] && [[ -z "$DH_GROUP_OFFERED" ]] && [[ "$curve_found" =~ ffdhe ]]; then - DH_GROUP_OFFERED="RFC7919/$curve_found" - DH_GROUP_LEN_P="${curve_found#ffdhe}" - fi - [[ ! "$curve_found" =~ ffdhe ]] && break - for (( i=0; i < nr_curves; i++ )); do - ! "${supported_curve[i]}" && [[ "${ffdhe_groups_output[i]}" == "$curve_found" ]] && break - done - [[ $i -eq $nr_curves ]] && break - supported_curve[i]=true - done - done - curves_offered="" - for (( i=0; i < nr_curves; i++ )); do - "${supported_curve[i]}" && curves_offered+="${ffdhe_groups_output[i]} " - done - curves_offered="$(strip_trailing_space "$curves_offered")" - if "$ffdhe_offered" && [[ -z "$curves_offered" ]] && [[ -z "$curve_found" ]]; then - # Some servers will fail if the supported_groups extension is present. - tls_sockets "03" "${ffdhe_cipher_list_hex:2}, 00,ff" "ephemeralkey" - sclient_success=$? - if [[ $sclient_success -eq 0 ]] || [[ $sclient_success -eq 2 ]]; then - temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - curve_found="${temp#*, }" - curve_found="${curve_found%%,*}" - fi - fi - if [[ -z "$curves_offered" ]] && [[ -n "$curve_found" ]]; then - # The server is not using one of the groups from RFC 7919. - if [[ -z "$DH_GROUP_OFFERED" ]]; then - # this global will get the name of the group either here or in run_logjam() - key_bitstring="$(awk '/-----BEGIN PUBLIC KEY/,/-----END PUBLIC KEY/ { print $0 }' $TEMPDIR/$NODEIP.parse_tls_serverhello.txt)" - get_common_prime "$jsonID" "$key_bitstring" "" - case $? in - 0) curves_offered="$DH_GROUP_OFFERED" - len_dh_p=$DH_GROUP_LEN_P ;; - 2) pr_bold " DH or FF group offered : " - prln_local_problem "Your $OPENSSL does not support the pkey utility." - fileout "$jsonID" "WARN" "$OPENSSL does not support the pkey utility." - esac - else - curves_offered="$DH_GROUP_OFFERED" - len_dh_p=$DH_GROUP_LEN_P - fi - fi - if [[ -n "$curves_offered" ]]; then - if [[ ! "$curves_offered" =~ ffdhe ]] || [[ ! "$curves_offered" =~ \ ]]; then - pr_bold " DH group offered: " - else - pr_bold " Finite field group: " - fi - if [[ "$curves_offered" =~ ffdhe ]]; then - # ok not to display them in italics: - pr_svrty_good "$curves_offered" - quality=6 - else - pr_dh "$curves_offered" "$len_dh_p" - quality=$? - fi - case "$quality" in - 1) quality_str="CRITICAL" ;; - 2) quality_str="HIGH" ;; - 3) quality_str="MEDIUM" ;; - 4) quality_str="LOW" ;; - 5) quality_str="INFO" ;; - 6|7) quality_str="OK" ;; - esac - if [[ "$curves_offered" =~ Unknown ]]; then - fileout "DH_groups" "$quality_str" "$curves_offered ($len_dh_p bits)" - else - fileout "DH_groups" "$quality_str" "$curves_offered" - fi - outln - fi - fi - if "$using_sockets"; then - protos_to_try="" - "$fs_tls13_offered" && protos_to_try="04-01 04-02" - # For TLS 1.2, find a supported cipher suite corresponding to each of the key types (RSA, ECDSA, DSS). - # Need to try each key type separately, otherwise not all supported signature algorithms will be found. - if "$fs_tls12_offered"; then - for (( i=0; i < nr_supported_ciphers; i++ )); do - ! "${ciphers_found[i]}" && continue - if [[ -z "$rsa_cipher" ]] && { [[ "${rfc_ciph[i]}" == TLS_DHE_RSA* ]] || - [[ "${rfc_ciph[i]}" == TLS_ECDHE_RSA* ]] || [[ "${ciph[i]}" == DHE-RSA-* ]] || - [[ "${ciph[i]}" == ECDHE-RSA-* ]]; }; then - rsa_cipher="${hexcode[i]}" - elif [[ -z "$ecdsa_cipher" ]] && { [[ "${rfc_ciph[i]}" == TLS_ECDHE_ECDSA* ]] || [[ "${ciph[i]}" == ECDHE-ECDSA-* ]]; }; then - ecdsa_cipher="${hexcode[i]}" - elif [[ -z "$dss_cipher" ]] && { [[ "${rfc_ciph[i]}" == TLS_DHE_DSS* ]] || [[ "${ciph[i]}" == DHE-DSS-* ]]; }; then - dss_cipher="${hexcode[i]}" - fi - done - [[ -n "$rsa_cipher" ]] && protos_to_try+=" 03-rsa-$rsa_cipher" - [[ -n "$ecdsa_cipher" ]] && protos_to_try+=" 03-ecdsa-$ecdsa_cipher" - [[ -n "$dss_cipher" ]] && protos_to_try+=" 03-dss-$dss_cipher" - fi - for proto in $protos_to_try; do - while true; do - i=0 - sigalgs_to_test="" - # A few servers get confused if the signature_algorithms extension contains too many entries. So: - # * For TLS 1.3, break the list into two and test each half separately. - # * For TLS 1.2, generally limit the signature_algorithms extension to algorithms that are consistent with the key type. - for hexc in "${sigalgs_hex[@]}"; do - if [[ "$proto" == 04* ]]; then - if ! "${tls13_supported_sigalgs[i]}"; then - if [[ "${proto##*-}" == 01 ]]; then - [[ $i -le 16 ]] && sigalgs_to_test+=", $hexc" - else - [[ $i -gt 16 ]] && sigalgs_to_test+=", $hexc" - fi - fi - elif ! "${tls12_supported_sigalgs[i]}"; then - if [[ "$proto" =~ rsa ]]; then - if [[ "${hexc:3:2}" == 01 ]] || [[ "${hexc:0:2}" == 08 ]]; then - sigalgs_to_test+=", $hexc" - fi - elif [[ "$proto" =~ dss ]]; then - [[ "${hexc:3:2}" == 02 ]] && sigalgs_to_test+=", $hexc" - else - if [[ "${hexc:3:2}" == 03 ]] || [[ "${hexc:0:2}" == 08 ]]; then - sigalgs_to_test+=", $hexc" - fi - fi - fi - i+=1 - done - [[ -z "$sigalgs_to_test" ]] && break - len1=$(printf "%02x" "$((2*${#sigalgs_to_test}/7))") - len2=$(printf "%02x" "$((2*${#sigalgs_to_test}/7+2))") - if [[ "$proto" == 04* ]]; then - tls_sockets "${proto%%-*}" "$TLS13_CIPHER" "all+" "00,0d, 00,$len2, 00,$len1, ${sigalgs_to_test:2}" - else - tls_sockets "${proto%%-*}" "${proto##*-}, 00,ff" "ephemeralkey" "00,0d, 00,$len2, 00,$len1, ${sigalgs_to_test:2}" - fi - [[ $? -eq 0 ]] || break - sigalg_found="$(awk -F ': ' '/^Peer signing digest/ { print $2 } ' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - [[ -n "$sigalg_found" ]] && sigalg_found="+$sigalg_found" - sigalg_found="$(awk -F ': ' '/^Peer signature type/ { print $2 } ' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")$sigalg_found" - i=0 - for hexc in "${sigalgs_hex[@]}"; do - [[ "${sigalgs_strings[i]}" == $sigalg_found ]] && break - i+=1 - done - [[ -z "${sigalgs_hex[i]}" ]] && break - if [[ "$proto" == 04* ]]; then - "${tls13_supported_sigalgs[i]}" && break - tls13_supported_sigalgs[i]=true - tls13_supported_sigalg_list+=" $sigalg_found" - else - "${tls12_supported_sigalgs[i]}" && break - tls12_supported_sigalgs[i]=true - tls12_supported_sigalg_list+=" $sigalg_found" - fi - done - done - tls12_supported_sigalg_list="${tls12_supported_sigalg_list:1}" - tls13_supported_sigalg_list="${tls13_supported_sigalg_list:1}" - if "$fs_tls12_offered"; then - pr_bold " TLS 1.2 sig_algs offered: " - if [[ -z "$(sed -e 's/[A-Za-z\-]*+SHA1//g' -e 's/[A-Za-z\-]*+MD5//g' -e 's/ //g' <<< "$tls12_supported_sigalg_list")" ]]; then - prln_svrty_critical "$(out_row_aligned_max_width "$tls12_supported_sigalg_list " " " $TERM_WIDTH)" - fileout "${jsonID}_TLS12_sig_algs" "CRITICAL" "$tls12_supported_sigalg_list" - else - out_row_aligned_max_width_by_entry "$tls12_supported_sigalg_list " " " $TERM_WIDTH pr_sigalg_quality - outln - if [[ "$tls12_supported_sigalg_list" =~ MD5 ]]; then - fileout "${jsonID}_TLS12_sig_algs" "HIGH" "$tls12_supported_sigalg_list" - elif [[ "$tls12_supported_sigalg_list" =~ SHA1 ]]; then - fileout "${jsonID}_TLS12_sig_algs" "LOW" "$tls12_supported_sigalg_list" - else - fileout "${jsonID}_TLS12_sig_algs" "INFO" "$tls12_supported_sigalg_list" - fi - fi - fi - if "$fs_tls13_offered"; then - pr_bold " TLS 1.3 sig_algs offered: " - # If only SHA1 and MD5 signature algorithms are supported, this is a critical finding. - # If SHA1 and/or MD5 are supported, but stronger algorithms are also supported, the - # severity is less. - if [[ -z "$(sed -e 's/[A-Za-z\-]*+SHA1//g' -e 's/[A-Za-z\-]*+MD5//g' -e 's/ //g' <<< "$tls13_supported_sigalg_list")" ]]; then - prln_svrty_critical "$(out_row_aligned_max_width "$tls13_supported_sigalg_list " " " $TERM_WIDTH)" - fileout "${jsonID}_TLS13_sig_algs" "CRITICAL" "$tls13_supported_sigalg_list" - else - out_row_aligned_max_width_by_entry "$tls13_supported_sigalg_list " " " $TERM_WIDTH pr_sigalg_quality - outln - if [[ "$tls13_supported_sigalg_list" =~ MD5 ]]; then - fileout "${jsonID}_TLS13_sig_algs" "HIGH" "$tls13_supported_sigalg_list" - elif [[ "$tls13_supported_sigalg_list" =~ SHA1 ]]; then - fileout "${jsonID}_TLS13_sig_algs" "LOW" "$tls13_supported_sigalg_list" - else - fileout "${jsonID}_TLS13_sig_algs" "INFO" "$tls13_supported_sigalg_list" - fi - fi - fi - fi - - tmpfile_handle ${FUNCNAME[0]}.txt - "$using_sockets" && HAS_DH_BITS="$has_dh_bits" - return 0 -} - - -# good source for configuration and bugs: https://wiki.mozilla.org/Security/Server_Side_TLS -# good start to read: https://en.wikipedia.org/wiki/Transport_Layer_Security#Attacks_against_TLS.2FSSL - - -npn_pre(){ - if [[ -n "$PROXY" ]]; then - pr_warning "not tested as proxies do not support proxying it" - fileout "NPN" "WARN" "not tested as proxies do not support proxying it" - return 1 - fi - if ! "$HAS_NPN"; then - pr_local_problem "$OPENSSL doesn't support NPN/SPDY"; - fileout "NPN" "WARN" "not tested $OPENSSL doesn't support NPN/SPDY" - return 7 - fi - return 0 -} - -alpn_pre(){ - if [[ -n "$PROXY" ]]; then - pr_warning "not tested as proxies do not support proxying it" - fileout "ALPN" "WARN" "not tested as proxies do not support proxying it" - return 1 - fi - if ! "$HAS_ALPN" && "$SSL_NATIVE"; then - prln_local_problem "$OPENSSL doesn't support ALPN/HTTP2"; - fileout "ALPN" "WARN" "not tested as $OPENSSL does not support it" - return 7 - fi - return 0 -} - -# modern browsers do not support it anymore but we should still test it at least for fingerprinting the server side -# Thus we don't label any support for NPN as good. -# FAST mode skips this test -run_npn() { - local tmpstr - local -i ret=0 - local jsonID="NPN" - - [[ -n "$STARTTLS" ]] && return 0 - "$FAST" && return 0 - pr_bold " NPN/SPDY " - if ! npn_pre; then - outln - return 0 - fi - $OPENSSL s_client $(s_client_options "-connect $NODEIP:$PORT $BUGS $SNI -nextprotoneg "$NPN_PROTOs"") $ERRFILE >$TMPFILE - [[ $? -ne 0 ]] && ret=1 - tmpstr="$(grep -a '^Protocols' $TMPFILE | sed 's/Protocols.*: //')" - if [[ -z "$tmpstr" ]] || [[ "$tmpstr" == " " ]]; then - outln "not offered" - fileout "$jsonID" "INFO" "not offered" - else - # now comes a strange thing: "Protocols advertised by server:" is empty but connection succeeded - if [[ "$tmpstr" =~ [h2|spdy|http] ]]; then - out "$tmpstr" - outln " (advertised)" - fileout "$jsonID" "INFO" "offered with $tmpstr (advertised)" - else - prln_cyan "please check manually, server response was ambiguous ..." - fileout "$jsonID" "INFO" "please check manually, server response was ambiguous ..." - ((ret++)) - fi - fi - # btw: nmap can do that too https://nmap.org/nsedoc/scripts/tls-nextprotoneg.html - # nmap --script=tls-nextprotoneg #NODE -p $PORT is your friend if your openssl doesn't want to test this - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - - -run_alpn() { - local tmpstr alpn_extn len - local -i ret=0 - local has_alpn_proto=false - local alpn_finding="" - local jsonID="ALPN" - - [[ -n "$STARTTLS" ]] && return 0 - pr_bold " ALPN/HTTP2 " - if ! alpn_pre; then - outln - return 0 - fi - for proto in $ALPN_PROTOs; do - # for some reason OpenSSL doesn't list the advertised protocols, so instead try common protocols - if "$HAS_ALPN"; then - $OPENSSL s_client $(s_client_options "-connect $NODEIP:$PORT $BUGS $SNI -alpn $proto") $ERRFILE >$TMPFILE - else - alpn_extn="$(printf "%02x" ${#proto}),$(string_to_asciihex "$proto")" - len="$(printf "%04x" $((${#proto}+1)))" - alpn_extn="${len:0:2},${len:2:2},$alpn_extn" - len="$(printf "%04x" $((${#proto}+3)))" - alpn_extn="00,10,${len:0:2},${len:2:2},$alpn_extn" - tls_sockets "03" "$TLS12_CIPHER" "all+" "$alpn_extn" - if [[ -r "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ]]; then - cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE - else - echo "" > $TMPFILE - fi - fi - tmpstr="$(awk -F':' '/^ALPN protocol*:/ { print $2 }' $TMPFILE)" - if [[ "$tmpstr" == *"$proto" ]]; then - if ! $has_alpn_proto; then - has_alpn_proto=true - else - out ", " - fi - # only h2 is what browser need to use HTTP/2.0 and brings a security,privacy and performance benefit - if [[ "$proto" == "h2" ]]; then - pr_svrty_good "$proto" - fileout "${jsonID}_HTTP2" "OK" "$proto" - else - out "$proto" - alpn_finding+="$proto" - fi - fi - done - if $has_alpn_proto; then - outln " (offered)" - # if h2 is not the only protocol: - [[ -n "$alpn_finding" ]] && fileout "$jsonID" "INFO" "$alpn_finding" - else - outln "not offered" - fileout "$jsonID" "INFO" "not offered" - fi - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - -# arg1: send string -# arg2: success string: an egrep pattern -# arg3: number of loops we should read from the buffer (optional, otherwise STARTTLS_SLEEP) -starttls_io() { - local nr_waits=$STARTTLS_SLEEP - local buffer="" - local -i i - - [[ -n "$3" ]] && waitsleep=$3 - [[ -z "$2" ]] && echo "FIXME $((LINENO))" - - # If there's a sending part it's IO. Postgres sends via socket and replies via - # strings "S". So there's no I part of IO ;-) - if [[ -n "$1" ]]; then - debugme echo -en "C: $1" - echo -en "$1" >&5 - fi - if [[ "$2" == JUSTSEND ]]; then - debugme echo -e "\n (only sent)\n" - dd of=/dev/null bs=512 count=1 <&5 2>/dev/null & - return 0 - fi - - # This seems a bit dangerous but works. No blockings yet. "if=nonblock" doesn't work on BSDs - buffer="$(dd bs=512 count=1 <&5 2>/dev/null)" - - for ((i=1; i < nr_waits; i++ )); do - [[ "$DEBUG" -ge 2 ]] && echo -en "\nS: " && echo $buffer - if [[ "$buffer" =~ $2 ]]; then - debugme echo " ---> reply matched \"$2\"" - # the fd sometimes still seem to contain chars which confuses the following TLS handshake, trying to empty: - # dd of=/dev/null bs=512 count=1 <&5 2>/dev/null - return 0 - else - # no match yet, more reading from fd helps. - buffer+=$(dd bs=512 count=1 <&5 2>/dev/null) - fi - done - return 1 -} - - -# Line-based send with newline characters appended (arg2 empty) -# arg2: debug_string -- what we had in the caller previously -starttls_just_send(){ - local -i ret=0 - - debugme echo "C: $1\r\n" - # We need cat here, otherwise the appended ELHO after STARTTLS will be in the next packet - printf "%b" "$1\r\n" | cat >&5 - ret=$? - if [[ $ret -eq 0 ]]; then - debugme echo " > succeeded: $2" - else - debugme echo " > failed: $2 ($ret)" - fi - return $ret -} - -# arg1: (optional): wait time -starttls_just_read(){ - local waitsleep=$STARTTLS_SLEEP - [[ -n "$1" ]] && waitsleep=$1 - if [[ "$DEBUG" -ge 2 ]]; then - echo "=== just read banner ===" - cat <&5 & - else - dd of=/dev/null count=8 <&5 2>/dev/null & - fi - wait_kill $! $waitsleep - return 0 -} - -starttls_full_read(){ - local cont_pattern="$1" - local end_pattern="$2" - local starttls_regex="$3" # optional: pattern we search for in the server's response - local debug_str="$4" # optional - local starttls_read_data=() - local one_line="" - local ret=0 - local ret_found=0 - local debugpad=" > found: " - local oldIFS="$IFS" - - debugme echo "=== reading banner ... ===" - if [[ -n "$starttls_regex" ]]; then - debugme echo "=== we'll have to search for \"$starttls_regex\" pattern ===" - # pre-set an error if we won't find the ~regex - ret_found=3 - fi - - IFS='' - # Now read handshake line by line and act on the args supplied. - # Exit the subshell if timeout has been hit (-t $STARTTLS_SLEEP) - while read -r -t $STARTTLS_SLEEP one_line; ret=$?; (exit $ret); do - debugme tmln_out "S: ${one_line}" - if [[ $DEBUG -ge 5 ]]; then - echo "end_pattern/cont_pattern: ${end_pattern} / ${cont_pattern}" - fi - if [[ -n "$starttls_regex" ]]; then - if [[ ${one_line} =~ $starttls_regex ]]; then - debugme tmln_out "${debugpad} ${one_line} " - # We don't exit here as the buffer is not empty. So we continue reading but save the status: - ret_found=0 - fi - fi - starttls_read_data+=("${one_line}") - if [[ ${one_line} =~ ${end_pattern} ]]; then - debugme tmln_out "${debugpad} ${one_line} " - IFS="${oldIFS}" - break - fi - if [[ ! ${one_line} =~ ${cont_pattern} ]]; then - debugme echo "=== full read syntax error, expected regex pattern ${cont_pattern} (cont) or ${end_pattern} (end) ===" - IFS="${oldIFS}" - ret_found=2 - break - fi - done <&5 - if [[ $ret_found -eq 0 ]]; then - # Print the debug statement we previously had in the caller function - [[ -n "$debug_str" ]] && debugme echo " >> $debug_str" - else - if [[ $ret -ge 128 ]]; then - debugme echo "=== timeout reading ===" - ret_found=$ret - fi - fi - IFS="${oldIFS}" - return $ret_found -} - -starttls_ftp_dialog() { - local -i ret=0 - local reSTARTTLS='^ AUTH' - - debugme echo "=== starting ftp STARTTLS dialog ===" - starttls_full_read '^220-' '^220 ' '' "received server greeting" && - starttls_just_send 'FEAT' "sent FEAT" && - starttls_full_read '^(211-| )' '^211 ' "${reSTARTTLS}" "received server features and checked STARTTLS availability" && - starttls_just_send 'AUTH TLS' "initiated STARTTLS" && - starttls_full_read '^234-' '^234 ' '' "received ack for STARTTLS" - ret=$? - debugme echo "=== finished ftp STARTTLS dialog with ${ret} ===" - return $ret -} - -# argv1: empty: SMTP, "lmtp" : LMTP -# argv2: payload for STARTTLS injection test -# -starttls_smtp_dialog() { - local greet_str="EHLO testssl.sh" - local proto="smtp" - local reSTARTTLS='^250[ -]STARTTLS' - local starttls="STARTTLS" - local -i ret=0 - - "$SNEAKY" && greet_str="EHLO google.com" - [[ -n "$2" ]] && starttls="$starttls\r\n$2" # this adds a payload if supplied - if [[ "$1" == lmtp ]]; then - proto="lmtp" - greet_str="LHLO testssl.sh" - fi - debugme echo "=== starting $proto STARTTLS dialog ===" - - starttls_full_read '^220-' '^220 ' '' "received server greeting" && - starttls_just_send "$greet_str" "sent $greet_str" && - starttls_full_read '^250-' '^250 ' "${reSTARTTLS}" "received server capabilities and checked STARTTLS availability" && - starttls_just_send "$starttls" "initiated STARTTLS" && - starttls_full_read '^220-' '^220 ' '' "received ack for STARTTLS" - ret=$? - debugme echo "=== finished $proto STARTTLS dialog with ${ret} ===" - return $ret -} - -# argv1: payload for STARTTLS injection test -# -starttls_pop3_dialog() { - local -i ret=0 - local starttls="STLS" - - [[ -n "$1" ]] && starttls="$starttls\r\n$1" # this adds a payload if supplied - debugme echo "=== starting pop3 STARTTLS dialog ===" - starttls_full_read '^\+OK' '^\+OK' '' "received server greeting" && - starttls_just_send "$starttls" "initiated STARTTLS" && - starttls_full_read '^\+OK' '^\+OK' '' "received ack for STARTTLS" - ret=$? - debugme echo "=== finished pop3 STARTTLS dialog with ${ret} ===" - return $ret -} - -# argv1: payload for STARTTLS injection test -# -starttls_imap_dialog() { - local -i ret=0 - local reSTARTTLS='^\* CAPABILITY(( .*)? IMAP4rev1( .*)? STARTTLS(.*)?|( .*)? STARTTLS( .*)? IMAP4rev1(.*)?)$' - local starttls="a002 STARTTLS" - - [[ -n "$1" ]] && starttls="$starttls\r\n$1" # this adds a payload if supplied - debugme echo "=== starting imap STARTTLS dialog ===" - starttls_full_read '^\* ' '^\* OK ' '' "received server greeting" && - starttls_just_send 'a001 CAPABILITY' "sent CAPABILITY" && - starttls_full_read '^\* ' '^a001 OK ' "${reSTARTTLS}" "received server capabilities and checked STARTTLS availability" && - starttls_just_send "$starttls" "initiated STARTTLS" && - starttls_full_read '^\* ' '^a002 OK ' '' "received ack for STARTTLS" - ret=$? - debugme echo "=== finished imap STARTTLS dialog with ${ret} ===" - return $ret -} - -# argv1: payload for STARTTLS injection test -# -starttls_sieve_dialog() { - local -i ret=0 - local starttls="STARTTLS" - - [[ -n "$1" ]] && starttls="$starttls\r\n$1" # this adds a payload if supplied - debugme echo "=== starting sieve STARTTLS dialog ===" - starttls_full_read '^"' '^OK ' '"STARTTLS"' "received server capabilities and checked STARTTLS availability" && - starttls_just_send "$starttls" "initiated STARTTLS" && - starttls_full_read '^OK ' '^OK ' '' "received ack for STARTTLS" - ret=$? - debugme echo "=== finished sieve STARTTLS dialog with ${ret} ===" - return $ret -} - -starttls_xmpp_dialog() { - local -i ret=0 - - debugme echo "=== starting xmpp STARTTLS dialog ===" - [[ -z $XMPP_HOST ]] && XMPP_HOST="$NODE" - - namespace="jabber:client" - [[ "$STARTTLS_PROTOCOL" == xmpp-server ]] && namespace="jabber:server" - - starttls_io "" 'starttls(.*)features' 1 && - starttls_io "" '" 'JUSTSEND' 2 - ret=$? - debugme echo "=== finished xmpp STARTTLS dialog with ${ret} ===" - return $ret -} - -starttls_nntp_dialog() { - local -i ret=0 - - debugme echo "=== starting nntp STARTTLS dialog ===" - starttls_full_read '$^' '^20[01] ' '' "received server greeting" && - starttls_just_send 'STARTTLS' "initiated STARTTLS" && - starttls_full_read '$^' '^382 ' '' "received ack for STARTTLS" - ret=$? - debugme echo "=== finished nntp STARTTLS dialog with ${ret} ===" - return $ret -} - -starttls_postgres_dialog() { - local -i ret=0 - local debugpad=" > " - local starttls_init=", x00, x00 ,x00 ,x08 ,x04 ,xD2 ,x16 ,x2F" - - debugme echo "=== starting postgres STARTTLS dialog ===" - socksend "${starttls_init}" 0 && debugme echo "${debugpad}initiated STARTTLS" && - starttls_io "" S 1 && debugme echo "${debugpad}received ack (=\"S\") for STARTTLS" - ret=$? - debugme echo "=== finished postgres STARTTLS dialog with ${ret} ===" - return $ret -} - - -# RFC 2251, 2830, RFC 4511 -# -starttls_ldap_dialog() { - local debugpad=" > " - local -i ret=0 - local msg_lenstr="" - local -i msg_len=0 - local buffer="" buffsize="" - local result_code="00" - local starttls_init=", - x30, x1d, x02, x01, # LDAP extendedReq - x01, # messageID: 1 - x77, x18, x80, x16, x31, x2e, x33, x2e, x36, x2e, # ProtocolOP: extendedReq - x31, x2e, x34, x2e, x31, x2e, x31, x34, x36, x36, x2e, x32, x30, x30, x33, x37" # OID for STATRTTLS = "1.3.6.1.4.1.1466.20037" - - debugme echo "=== starting LDAP STARTTLS dialog ===" - socksend "${starttls_init}" 0 && debugme echo "${debugpad}initiated STARTTLS" && - buffer=$(sockread_fast 256) - [[ $DEBUG -ge 4 ]] && safe_echo "$debugpad $buffer\n" - - # We have two different scenarios: AD and OpenLDAP. And maybe more we don't more of yet. - # OpenLDAP-like reply is - # 30 0c 02 01 01 78 07 0a 01 00 04 00 04 00 - # ^^ buffsize ^^ LDAP result code (0 -> success) - # - # see https://git.openldap.org/openldap/openldap/-/blob/master/include/ldap.h - # return values in https://www.rfc-editor.org/rfc/rfc2251#page-45 and e.g. - - # AD-like is - # error: 30 84 00 00 00 7d 02 01 01 78 84 00 00 00 74 0a 01 34 04 00 04 55 30 30 [.. LdapErr, string, OID.. ] - # success 30 84 00 00 00 28 02 01 01 78 84 00 00 00 1F 0A 01 00 04 00 04 00 8A 16 [ .. OID .. ] - # ^^ buffsize ^^ LDAP result code (0 -> success) - - # We assume that AD servers probably all have x84. It was deducted from a number of hosts. - # It maybe needs to be amended for other implementations. - # Basically using ldap_ExtendedResponse_parse() in apps/s_client.c of openssl would be - # more robust but it is kind of hard to understand. - # - # Bottom line: We'll look at the 9th or the 17th byte when retrieving the result code - # depending what the buffsize is. - - buffsize="${buffer:2:2}" - - case $buffsize in - 0C) result_code="${buffer:18:2}" ;; - 84) result_code="${buffer:34:2}" ;; - esac - [[ $DEBUG -ge 2 ]] && safe_echo "$debugpad buffsize: $buffsize / LDAP result code: $result_code \n" - - case $result_code in - 00) ret=0 ;; - # success - 01) ret=1 ;; - # OpenLDAP: operationsError - 02) ret=2 - # OpenLDAP: protocolError (text msg: "unsupported extended operation") e.g. when STARTTLS not supported - if [[ $DEBUG -ge 2 ]]; then - msg_lenstr=$(hex2dec ${buffer:26:02}) - msg_len=$((2 * msg_lenstr)) - safe_echo "$debugpad $(hex2binary "${buffer:28:$msg_len}")" - fi ;; - 34) # This (52 in dec) seems to be the error code for AD when there's no STARTTLS - [[ $DEBUG -ge 2 ]] && safe_echo " seems AD server with no STARTTLS\n" - ret=52 ;; - *) [[ $DEBUG -ge 2 ]] && safe_echo "$debugpad $(hex2dec "${buffer:28:2}")" - ret=127 ;; - esac - - debugme echo "=== finished LDAP STARTTLS dialog with ${ret} ===" - return $ret -} - -starttls_mysql_dialog() { - local debugpad=" > " - local -i ret=0 - local starttls_init=" - , x20, x00, x00, x01, # payload_length, sequence_id - x85, xae, xff, x00, # capability flags, CLIENT_SSL always set - x00, x00, x00, x01, # max-packet size - x21, # character set - x00, x00, x00, x00, x00, x00, x00, x00, # string[23] reserved (all [0]) - x00, x00, x00, x00, x00, x00, x00, x00, - x00, x00, x00, x00, x00, x00, x00" - - debugme echo "=== starting mysql STARTTLS dialog ===" - socksend "${starttls_init}" 0 && debugme echo "${debugpad}initiated STARTTLS" && - starttls_just_read 1 "read succeeded" - # 1 is the timeout value which only MySQL needs. Note, there seems no response whether STARTTLS - # succeeded. We could try harder, see https://github.com/openssl/openssl/blob/master/apps/s_client.c - # but atm this seems sufficient as later we will fail if there's no STARTTLS. - # BUT: there seem to be cases when the handshake fails (8S01Bad handshake --> 30 38 53 30 31 42 61 64 20 68 61 6e 64 73 68 61 6b 65). - # also there's a banner in the reply "mysql_native_password" - # TODO: We could detect if the server supports STARTTLS via the "Server Capabilities" - # bit field, but we'd need to parse the binary stream, with greater precision than regex. - ret=$? - debugme echo "=== finished mysql STARTTLS dialog with ${ret} ===" - return $ret -} - -starttls_telnet_dialog() { - local debugpad=" > " - local tnres="" - local -i ret=0 - local msg1=" - , xff, xfb, x2e" - local msg2=" - , xff, xfa, x2e, x01, xff, xf0 - " - - debugme echo "=== starting telnet STARTTLS dialog ===" - socksend "${msg1}" 0 && debugme echo "${debugpad}initiated STARTTLS" && - socksend "${msg2}" 1 && - tnres=$(sockread_fast 20) && debugme echo "read succeeded" - [[ $DEBUG -ge 6 ]] && safe_echo "$debugpad $tnres\n" - # check for START_TLS and FOLLOWS - if [[ ${tnres:10:2} == 2E ]] && [[ ${tnres:12:2} == 01 ]]; then - ret=0 - else - ret=1 - fi - debugme echo "=== finished telnet STARTTLS dialog with ${ret} ===" - return $ret -} - -# arg1: fd for socket -- which we don't use yes as it is a hassle (not clear whether it works under every bash version) -# arg2: optional: for STARTTLS additional command to be injected -# returns 6 if opening the socket caused a problem, 1 if STARTTLS handshake failed, 0: all ok -# -fd_socket() { - local fd="$1" - local payload="$2" - local proyxline="" - local nodeip="$(tr -d '[]' <<< $NODEIP)" # sockets do not need the square brackets we have of IPv6 addresses - # we just need do it here, that's all! - if [[ -t 5 ]]; then - pr_warning "$PROG_NAME: unable to open a socket because of a tty conflict" - return 6 - fi - if [[ -n "$PROXY" ]]; then - # PROXYNODE works better than PROXYIP on modern versions of squid - if ! exec 5<> /dev/tcp/${PROXYNODE}/${PROXYPORT}; then - outln - pr_warning "$PROG_NAME: unable to open a socket to proxy $PROXYNODE:$PROXYPORT" - return 6 - fi - if "$DNS_VIA_PROXY"; then - printf -- "%b" "CONNECT $NODE:$PORT HTTP/1.0\n\n" >&5 - else - printf -- "%b" "CONNECT $nodeip:$PORT HTTP/1.0\n\n" >&5 - fi - while true; do - read -t $PROXY_WAIT -r proyxline <&5 - if [[ $? -ge 128 ]]; then - pr_warning "Proxy timed out. Unable to CONNECT via proxy. " - close_socket 5 - return 6 - elif [[ "${proyxline%/*}" == HTTP ]]; then - proyxline=${proyxline#* } - if [[ "${proyxline%% *}" != 200 ]]; then - pr_warning "Unable to CONNECT via proxy. " - [[ "$PORT" != 443 ]] && prln_warning "Check whether your proxy supports port $PORT and the underlying protocol." - close_socket 5 - return 6 - fi - fi - if [[ "$proyxline" == $'\r' ]] || [[ -z "$proyxline" ]] ; then - break - fi - done - # For the following execs: 2>/dev/null would remove a potential error message, but disables debugging. - # First we check whether a socket connect timeout was specified. We exec the connect in a subshell, - # then we'll see whether we can connect. If not we take the emergency exit. If we're still alive we'll - # proceed with the "usual case", see below. - elif [[ -n "$CONNECT_TIMEOUT" ]]; then - if ! $TIMEOUT_CMD $CONNECT_TIMEOUT bash -c "exec 5<>/dev/tcp/$nodeip/$PORT"; then - ((NR_SOCKET_FAIL++)) - connectivity_problem $NR_SOCKET_FAIL $MAX_SOCKET_FAIL "TCP connect problem" "repeated TCP connect problems (connect timeout), giving up" - outln - pr_warning "Unable to open a socket to $NODEIP:$PORT. " - return 6 - fi - fi - # Now comes the usual case - if [[ -z "$PROXY" ]] && ! exec 5<>/dev/tcp/$nodeip/$PORT; then - ((NR_SOCKET_FAIL++)) - connectivity_problem $NR_SOCKET_FAIL $MAX_SOCKET_FAIL "TCP connect problem" "repeated TCP connect problems, giving up" - outln - pr_warning "Unable to open a socket to $NODEIP:$PORT. " - return 6 - fi - - if [[ -n "$STARTTLS" ]]; then - case "$STARTTLS_PROTOCOL" in # port - ftp|ftps) # https://tools.ietf.org/html/rfc4217, https://tools.ietf.org/html/rfc959 - starttls_ftp_dialog - ;; - smtp|smtps) # SMTP, see https://tools.ietf.org/html/rfc{2033,3207,5321} - starttls_smtp_dialog "" "$payload" - ;; - lmtp|lmtps) # LMTP, see https://tools.ietf.org/html/rfc{2033,3207,5321} - starttls_smtp_dialog lmtp - ;; - pop3|pop3s) # POP, see https://tools.ietf.org/html/rfc2595 - starttls_pop3_dialog "$payload" - ;; - nntp|nntps) # NNTP, see https://tools.ietf.org/html/rfc4642 - starttls_nntp_dialog - ;; - imap|imaps) # IMAP, https://tools.ietf.org/html/rfc2595, https://tools.ietf.org/html/rfc3501 - starttls_imap_dialog "$payload" - ;; - sieve) # MANAGESIEVE, https://tools.ietf.org/html/rfc5804 - starttls_sieve_dialog "$payload" - ;; - irc|ircs) # IRC, https://ircv3.net/specs/extensions/tls-3.1.html, https://ircv3.net/specs/core/capability-negotiation.html - fatal "FIXME: IRC+STARTTLS not yet supported" $ERR_NOSUPPORT - ;; - ldap|ldaps) # LDAP, https://tools.ietf.org/html/rfc2830#section-2.1, https://tools.ietf.org/html/rfc4511 - # https://ldap.com/ldapv3-wire-protocol-reference-extended/ - #fatal "FIXME: LDAP+STARTTLS over sockets not supported yet (try \"--ssl-native\")" $ERR_NOSUPPORT - starttls_ldap_dialog - ;; - acap|acaps) # ACAP = Application Configuration Access Protocol, see https://tools.ietf.org/html/rfc2595 - fatal "ACAP Easteregg: not implemented -- probably never will" $ERR_NOSUPPORT - ;; - xmpp|xmpps|xmpp-server) # XMPP, see https://tools.ietf.org/html/rfc6120 - starttls_xmpp_dialog - # IM observatory: https://xmpp.net , XMPP server directory: https://xmpp.net/directory.php - ;; - postgres) # Postgres SQL, see https://www.postgresql.org/docs/devel/protocol-message-formats.html - starttls_postgres_dialog - ;; - mysql) # MySQL, see https://dev.mysql.com/doc/internals/en/x-protocol-lifecycle-lifecycle.html#x-protocol-lifecycle-tls-extension - starttls_mysql_dialog - ;; - telnet) # captured from a tn3270 negotiation against z/VM 7.2. Also, see OpenSSL apps/s_client.c for the handling of PROTO_TELNET - starttls_telnet_dialog - ;; - *) # we need to throw an error here -- otherwise testssl.sh treats the STARTTLS protocol as plain SSL/TLS which leads to FP - fatal "FIXME: STARTTLS protocol $STARTTLS_PROTOCOL is not supported yet" $ERR_NOSUPPORT - esac - ret=$? - case $ret in - 0) return 0 ;; - 3) fatal "No STARTTLS found in handshake" $ERR_CONNECT ;; - *) if [[ $ret -eq 2 ]] && [[ -n "$payload" ]]; then - # We don't want this handling for STARTTLS injection - return 0 - fi - ((NR_STARTTLS_FAIL++)) - # This are mostly timeouts here (code >=128). We give the client a chance to try again later. For cases - # where we have no STARTTLS in the server banner however - ret code=3 - we don't need to try again - connectivity_problem $NR_STARTTLS_FAIL $MAX_STARTTLS_FAIL "STARTTLS handshake failed (code: $ret)" "repeated STARTTLS problems, giving up ($ret)" - return 6 ;; - esac - fi - # Plain socket ok, yes or no? - [[ $? -eq 0 ]] && return 0 - return 1 -} - -# arg1: socket fd but atm we use 5 anyway, see comment for fd_socket() -# -close_socket(){ - local fd="$1" - - exec 5<&- - exec 5>&- - return 0 -} - -send_close_notify() { - local detected_tlsversion="$1" - - debugme echo "sending close_notify..." - if [[ $detected_tlsversion == 0300 ]]; then - socksend ",x15, x03, x00, x00, x02, x02, x00" 0 - else - socksend ",x15, x03, x01, x00, x02, x02, x00" 0 - fi -} - -# Format string properly for socket -# ARG1: any commented sequence of two bytes hex, separated by commas. It can contain comments, new lines, tabs and white spaces -# NW_STR holds the global with the string prepared for printf, like '\x16\x03\x03\' -code2network() { - NW_STR=$(sed -e 's/,/\\\x/g' <<< "$1" | sed -e 's/# .*$//g' -e 's/ //g' -e '/^$/d' | tr -d '\n' | tr -d '\t') -} - -# sockets inspired by https://blog.chris007.de/using-bash-for-network-socket-operation/ -# ARG1: hexbytes separated by commas, with a leading comma -# ARG2: seconds to sleep -socksend_clienthello() { - local data="" - - code2network "$1" - data="$NW_STR" - [[ "$DEBUG" -ge 4 ]] && echo && echo "\"$data\"" - if [[ -z "$PRINTF" ]] ;then - # We could also use "dd ibs=1M obs=1M" here but is seems to be at max 3% slower - printf -- "$data" | cat >&5 2>/dev/null & - else - $PRINTF -- "$data" 2>/dev/null >&5 2>/dev/null & - fi - sleep $USLEEP_SND -} - - -# ARG1: hexbytes -- preceded by x -- separated by commas, with a leading comma -# ARG2: seconds to sleep -socksend() { - local data line - - # read line per line and strip comments (bash internal func can't handle multiline statements - data="$(while read line; do - printf "${line%%\#*}" - done <<< "$1" )" - data="${data// /}" # strip ' ' - data="${data//,/\\}" # s&r , by \ - [[ $DEBUG -ge 4 ]] && echo && echo "\"$data\"" - if [[ -z "$PRINTF" ]] ;then - printf -- "$data" | cat >&5 2>/dev/null & - else - $PRINTF -- "$data" 2>/dev/null >&5 2>/dev/null & - fi - sleep $2 -} - - -# Reads from socket. Uses SOCK_REPLY_FILE global to save socket reply -# Not blocking, polling -# ARG1: blocksize for reading -# -sockread() { - [[ -z "$2" ]] && maxsleep=$MAX_WAITSOCK || maxsleep=$2 - SOCK_REPLY_FILE=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 - dd bs=$1 of=$SOCK_REPLY_FILE count=1 <&5 2>/dev/null & - wait_kill $! $maxsleep - return $? -} - -# Reads from socket. Utilises a pipe. Output is ASCII. -# Faster as previous, blocks however when socket stream is empty -# ARG1: blocksize for reading -# -sockread_fast() { - dd bs=$1 count=1 <&5 2>/dev/null | hexdump -v -e '16/1 "%02X"' -} - -len2twobytes() { - local len_arg1=${#1} - [[ $len_arg1 -le 2 ]] && LEN_STR=$(printf "00, %02s \n" "$1") - [[ $len_arg1 -eq 3 ]] && LEN_STR=$(printf "0%s, %02s \n" "${1:0:1}" "${1:1:2}") - [[ $len_arg1 -eq 4 ]] && LEN_STR=$(printf "%02s, %02s \n" "${1:0:2}" "${1:2:2}") -} - - -get_pub_key_size() { - local pubkey pubkeybits - local -i i len1 len - - "$HAS_PKEY" || return 1 - - # OpenSSL displays the number of bits for RSA and ECC - pubkeybits=$($OPENSSL x509 -noout -pubkey -in $HOSTCERT 2>>$ERRFILE | $OPENSSL pkey -pubin -text_pub 2>>$ERRFILE) - if [[ "$pubkeybits" =~ E[Dd]25519 ]]; then - echo "Server public key is 253 bit" >> $TMPFILE - return 0 - elif [[ "$pubkeybits" =~ E[Dd]448 ]]; then - echo "Server public key is 456 bit" >> $TMPFILE - return 0 - fi - pubkeybits=$(awk -F'(' '/Public-Key/ { print $2 }' <<< "$pubkeybits") - if [[ -n $pubkeybits ]]; then - # remainder e.g. "256 bit)" - pubkeybits="${pubkeybits//\)/}" - echo "Server public key is $pubkeybits" >> $TMPFILE - else - # This extracts the public key for DSA, DH, and GOST - pubkey=$($OPENSSL x509 -noout -pubkey -in $HOSTCERT 2>>$ERRFILE | $OPENSSL pkey -pubin -outform DER 2>>$ERRFILE | hexdump -v -e '16/1 "%02X"') - [[ -z "$pubkey" ]] && return 1 - # Skip over tag and length of subjectPublicKeyInfo - i=2 - len1="0x${pubkey:i:2}" - if [[ $len1 -lt 0x80 ]]; then - i+=2 - else - len1=$((len1-0x80)) - i+=$((2*len1+2)) - fi - - # Skip over algorithm field - i+=2 - len1="0x${pubkey:i:2}" - i+=2 - if [[ $len1 -lt 0x80 ]]; then - i+=$((2*len1)) - else - case $len1 in - 129) len="0x${pubkey:i:2}" ;; - 130) len="0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - ;; - 131) len="0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - ;; - 132) len="0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - ;; - esac - i+=$((2+2*len)) - fi - - # Next is the public key BIT STRING. Skip over tag, length, and number of unused bits. - i+=2 - len1="0x${pubkey:i:2}" - if [[ $len1 -lt 0x80 ]]; then - i+=4 - else - len1=$((len1-0x80)) - i+=$((2*len1+4)) - fi - - # Now get the length of the public key - i+=2 - len1="0x${pubkey:i:2}" - i+=2 - if [[ $len1 -lt 0x80 ]]; then - len=$len1 - else - case $len1 in - 129) len="0x${pubkey:i:2}" ;; - 130) len="0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - ;; - 131) len="0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - ;; - 132) len="0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - i+=2 - len=256*$len+"0x${pubkey:i:2}" - ;; - esac - fi - len=$((8*len)) # convert from bytes to bits - pubkeybits="$(printf "%d" $len)" - echo "Server public key is $pubkeybits bit" >> $TMPFILE - fi - return 0 -} - -# Extract the DH ephemeral key from the ServerKeyExchange message -get_dh_ephemeralkey() { - local tls_serverkeyexchange_ascii="$1" - local -i tls_serverkeyexchange_ascii_len offset - local dh_p dh_g dh_y dh_param len1 key_bitstring - local -i i dh_p_len dh_g_len dh_y_len dh_param_len - - "$HAS_PKEY" || return 1 - - tls_serverkeyexchange_ascii_len=${#tls_serverkeyexchange_ascii} - dh_p_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:0:4}") - offset=4+$dh_p_len - if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - return 1 - fi - - # Subtract any leading 0 bytes - for (( i=4; i < offset; i+=2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_p_len=$dh_p_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - return 1 - fi - dh_p="${tls_serverkeyexchange_ascii:i:dh_p_len}" - - dh_g_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - i=4+$offset - offset+=4+$dh_g_len - if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - return 1 - fi - # Subtract any leading 0 bytes - for (( 1; i < offset; i+=2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_g_len=$dh_g_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - return 1 - fi - dh_g="${tls_serverkeyexchange_ascii:i:dh_g_len}" - - dh_y_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - i=4+$offset - offset+=4+$dh_y_len - if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - return 1 - fi - # Subtract any leading 0 bytes - for (( 1; i < offset; i+=2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_y_len=$dh_y_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - return 1 - fi - dh_y="${tls_serverkeyexchange_ascii:i:dh_y_len}" - - # The following code assumes that all lengths can be encoded using at most 2 bytes, - # which just means that the encoded length of the public key must be less than - # 65,536 bytes. If the length is anywhere close to that, it is almost certainly an - # encoding error. - if [[ $dh_p_len+$dh_g_len+$dh_y_len -ge 131000 ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - return 1 - fi - # make ASN.1 INTEGER of p, g, and Y - [[ "0x${dh_p:0:1}" -ge 8 ]] && dh_p_len+=2 && dh_p="00$dh_p" - if [[ $dh_p_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_p_len/2)))" - elif [[ $dh_p_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_p_len/2)))" - else - len1="82$(printf "%04x" $((dh_p_len/2)))" - fi - dh_p="02${len1}$dh_p" - - [[ "0x${dh_g:0:1}" -ge 8 ]] && dh_g_len+=2 && dh_g="00$dh_g" - if [[ $dh_g_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_g_len/2)))" - elif [[ $dh_g_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_g_len/2)))" - else - len1="82$(printf "%04x" $((dh_g_len/2)))" - fi - dh_g="02${len1}$dh_g" - - [[ "0x${dh_y:0:1}" -ge 8 ]] && dh_y_len+=2 && dh_y="00$dh_y" - if [[ $dh_y_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_y_len/2)))" - elif [[ $dh_y_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_y_len/2)))" - else - len1="82$(printf "%04x" $((dh_y_len/2)))" - fi - dh_y="02${len1}$dh_y" - - # Make a SEQUENCE of p and g - dh_param_len=${#dh_p}+${#dh_g} - if [[ $dh_param_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_param_len/2)))" - elif [[ $dh_param_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_param_len/2)))" - else - len1="82$(printf "%04x" $((dh_param_len/2)))" - fi - dh_param="30${len1}${dh_p}${dh_g}" - - # Make a SEQUENCE of the parameters SEQUENCE and the OID - dh_param_len=22+${#dh_param} - if [[ $dh_param_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_param_len/2)))" - elif [[ $dh_param_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_param_len/2)))" - else - len1="82$(printf "%04x" $((dh_param_len/2)))" - fi - dh_param="30${len1}06092A864886F70D010301${dh_param}" - - # Encapsulate public key, y, in a BIT STRING - dh_y_len=${#dh_y}+2 - if [[ $dh_y_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_y_len/2)))" - elif [[ $dh_y_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_y_len/2)))" - else - len1="82$(printf "%04x" $((dh_y_len/2)))" - fi - dh_y="03${len1}00$dh_y" - - # Create the public key SEQUENCE - i=${#dh_param}+${#dh_y} - if [[ $i -lt 256 ]]; then - len1="$(printf "%02x" $((i/2)))" - elif [[ $i -lt 512 ]]; then - len1="81$(printf "%02x" $((i/2)))" - else - len1="82$(printf "%04x" $((i/2)))" - fi - key_bitstring="30${len1}${dh_param}${dh_y}" - key_bitstring="$(hex2binary "$key_bitstring" | $OPENSSL pkey -pubin -inform DER 2> $ERRFILE)" - [[ -z "$key_bitstring" ]] && return 1 - tm_out "$key_bitstring" - return 0 -} - -# arg1: name of file with socket reply -# arg2: true if entire server hello should be parsed -# return values: 0=no SSLv2 (reset) -# 1=no SSLv2 (plaintext reply like it happens with OLS webservers) -# 3=SSLv2 supported (in $TEMPDIR/$NODEIP.sslv2_sockets.dd is reply for further processing -# --> there could be checked whether ciphers e.g have been returned at all (or anything else) -# 4=looks like an STARTTLS 5xx message -# 6=socket couldn't be opened -# 7=strange reply we can't deal with -parse_sslv2_serverhello() { - local ret v2_hello_ascii v2_hello_initbyte v2_hello_length - local v2_hello_handshake v2_cert_type v2_hello_cert_length - local v2_hello_cipherspec_length - local -i certificate_len nr_ciphers_detected offset i - local ret=3 - local parse_complete="false" - # SSLv2 server hello: in hex representation, see below - # byte 1+2: length of server hello 0123 - # 3: 04=Handshake message, server hello 45 - # 4: session id hit or not (boolean: 00=false, this 67 - # is the normal case) - # 5: certificate type, 01 = x509 89 - # 6+7 version (00 02 = SSLv2) 10-13 - # 8+9 certificate length 14-17 - # 10+11 cipher spec length 17-20 - # 12+13 connection id length - # [certificate length] ==> certificate - # [cipher spec length] ==> ciphers GOOD: HERE ARE ALL CIPHERS ALREADY! - - # Note: recent SSL/TLS stacks reply with a TLS alert on a SSLv2 client hello. - # The TLS error message is different and could be used for fingerprinting. - - if [[ "$2" == "true" ]]; then - parse_complete=true - fi - "$parse_complete" && echo "======================================" > $TMPFILE - - v2_hello_ascii=$(hexdump -v -e '16/1 "%02X"' $1) - v2_hello_ascii="${v2_hello_ascii%%[!0-9A-F]*}" - [[ "$DEBUG" -ge 5 ]] && echo "$v2_hello_ascii" - if [[ -z "$v2_hello_ascii" ]]; then - ret=0 # 1 line without any blanks: no server hello received - debugme echo "server hello empty" - else - # now scrape two bytes out of the reply per byte - v2_hello_initbyte="${v2_hello_ascii:0:1}" # normally this belongs to the next, should be 8! - v2_hello_length="${v2_hello_ascii:1:3}" # + 0x8000 see above - v2_hello_handshake="${v2_hello_ascii:4:2}" - v2_cert_type="${v2_hello_ascii:8:2}" - v2_hello_cert_length="${v2_hello_ascii:14:4}" - v2_hello_cipherspec_length="${v2_hello_ascii:18:4}" - - V2_HELLO_CIPHERSPEC_LENGTH=$(printf "%d\n" "0x$v2_hello_cipherspec_length" 2>/dev/null) - [[ $? -ne 0 ]] && ret=7 - - if [[ "${v2_hello_ascii:0:2}" == "35" ]] && "$do_starttls"; then - # this could be a 500/5xx for some weird reason where the STARTTLS handshake failed - debugme echo "$(hex2ascii "$v2_hello_ascii")" - ret=4 - elif [[ "${v2_hello_ascii:0:4}" == "1503" ]]; then - # Cloudflare does this, OpenSSL 1.1.1 and picoTLS. With different alert messages - # Just in case somebody's interested in the exact error, we deliver it ;-) - debugme echo -n ">TLS< alert message discovered: ${v2_hello_ascii} " - case "${v2_hello_ascii:10:2}" in - 01) debugme echo "(01/warning: 0x"${v2_hello_ascii:12:2}"/$(tls_alert "${v2_hello_ascii:12:2}"))" ;; - 02) debugme echo "(02/fatal: 0x"${v2_hello_ascii:12:2}"/$(tls_alert "${v2_hello_ascii:12:2}"))" ;; - *) debugme echo "("${v2_hello_ascii:10:2}" : "${v2_hello_ascii:12:2}"))" ;; - esac - ret=0 - elif [[ $v2_hello_initbyte != "8" ]] || [[ $v2_hello_handshake != "04" ]]; then - ret=1 - if [[ $DEBUG -ge 2 ]]; then - echo "no correct server hello" - echo "SSLv2 server init byte: 0x0$v2_hello_initbyte" - echo "SSLv2 hello handshake : 0x$v2_hello_handshake" - fi - fi - - if [[ $DEBUG -ge 3 ]]; then - echo "SSLv2 server hello length: 0x0$v2_hello_length" - echo "SSLv2 certificate type: 0x$v2_cert_type" - echo "SSLv2 certificate length: 0x$v2_hello_cert_length" - echo "SSLv2 cipher spec length: 0x$v2_hello_cipherspec_length" - fi - - if "$parse_complete" && [[ $((2*$(hex2dec "$v2_hello_length"))) -ne $((${#v2_hello_ascii}-4)) ]]; then - ret=7 - fi - fi - - "$parse_complete" || return $ret - - # not sure why we need this - rm -f $HOSTCERT - > $TEMPDIR/intermediatecerts.pem - if [[ $ret -eq 3 ]]; then - certificate_len=2*$(hex2dec "$v2_hello_cert_length") - - if [[ "$v2_cert_type" == "01" ]] && [[ "$v2_hello_cert_length" != "00" ]]; then - hex2binary "${v2_hello_ascii:26:certificate_len}" | \ - $OPENSSL x509 -inform DER -outform PEM -out $HOSTCERT 2>$ERRFILE - if [[ $? -ne 0 ]]; then - debugme echo "Malformed certificate in ServerHello." - return 1 - fi - get_pub_key_size - echo "======================================" >> $TMPFILE - fi - - # Output list of supported ciphers - offset=$((certificate_len+26)) - nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) - for (( i=0 ; i> $TMPFILE - offset=$((offset+6)) - done - echo "======================================" >> $TMPFILE - - tmpfile_handle ${FUNCNAME[0]}.txt - fi - return $ret -} - -# arg1: hash function -# arg2: key -# arg3: text -hmac() { - local hash_fn="$1" - local key="$2" text="$3" output - local -i ret - - if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ $OSSL_VER_MAJOR == 3 ]]; then - output="$(hex2binary "$text" | $OPENSSL mac -macopt digest:"${hash_fn/-/}" -macopt hexkey:"$key" HMAC 2>/dev/null)" - ret=$? - tm_out "$(strip_lf "$output")" - else - output="$(hex2binary "$text" | $OPENSSL dgst "$hash_fn" -mac HMAC -macopt hexkey:"$key" 2>/dev/null)" - ret=$? - tm_out "${output#*= }" - fi - return $ret -} - -# arg1: hash function -# arg2: key -# arg3: transcript -# Compute the HMAC of the hash of the transcript -hmac-transcript() { - local hash_fn="$1" - local key="$2" transcript="$3" output - local -i ret - - if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ $OSSL_VER_MAJOR == 3 ]]; then - output="$(hex2binary "$transcript" | \ - $OPENSSL dgst "$hash_fn" -binary 2>/dev/null | \ - $OPENSSL mac -macopt digest:"${hash_fn/-/}" -macopt hexkey:"$key" HMAC 2>/dev/null)" - ret=$? - tm_out "$(toupper "$(strip_lf "$output")")" - else - output="$(hex2binary "$transcript" | \ - $OPENSSL dgst "$hash_fn" -binary 2>/dev/null | \ - $OPENSSL dgst "$hash_fn" -mac HMAC -macopt hexkey:"$key" 2>/dev/null)" - ret=$? - tm_out "$(toupper "${output#*= }")" - fi - return $ret -} - -# arg1: hash function -# arg2: pseudorandom key (PRK) -# arg2: info -# arg3: length of output keying material in octets -# See RFC 5869, Section 2.3 -hkdf-expand() { - local hash_fn="$1" - local prk="$2" info="$3" output="" - local -i out_len="$4" - local -i i n hash_len ret - local counter - local ti tim1 # T(i) and T(i-1) - - case "$hash_fn" in - "-sha256") hash_len=32 ;; - "-sha384") hash_len=48 ;; - *) return 7 - esac - - n=$out_len/$hash_len - [[ $((out_len%hash_len)) -ne 0 ]] && n+=1 - - tim1="" - for (( i=1; i <= n; i++ )); do - counter="$(printf "%02X\n" $i)" - ti="$(hmac "$hash_fn" "$prk" "$tim1$info$counter")" - [[ $? -ne 0 ]] && return 7 - output+="$ti" - tim1="$ti" - done - out_len=$((2*out_len)) - tm_out "${output:0:out_len}" - return 0 -} - -# arg1: hash function -# arg2: secret -# arg3: label -# arg4: context -# arg5: length -# See RFC 8446, Section 7.1 -hkdf-expand-label() { - local hash_fn="$1" - local secret="$2" label="$3" - local context="$4" - local -i length="$5" - local hkdflabel hkdflabel_label hkdflabel_context - local hkdflabel_length - local -i len - - hkdflabel_length="$(printf "%04X\n" "$length")" - if [[ "${TLS_SERVER_HELLO:8:2}" == 7F ]] && [[ 0x${TLS_SERVER_HELLO:10:2} -lt 0x14 ]]; then - # "544c5320312e332c20" = "TLS 1.3, " - hkdflabel_label="544c5320312e332c20$label" - else - # "746c73313320" = "tls13 " - hkdflabel_label="746c73313320$label" - fi - len=${#hkdflabel_label}/2 - hkdflabel_label="$(printf "%02X\n" "$len")$hkdflabel_label" - len=${#context}/2 - hkdflabel_context="$(printf "%02X\n" "$len")$context" - hkdflabel="$hkdflabel_length$hkdflabel_label$hkdflabel_context" - - hkdf-expand "$hash_fn" "$secret" "$hkdflabel" "$length" - return $? -} - -# arg1: hash function -# arg2: secret -# arg3: label -# arg4: ASCII-HEX of messages -# See RFC 8446, Section 7.1 -derive-secret() { - local hash_fn="$1" - local secret="$2" label="$3" messages="$4" - local hash_messages - local -i hash_len retcode - - case "$hash_fn" in - "-sha256") hash_len=32 ;; - "-sha384") hash_len=48 ;; - *) return 7 - esac - - hash_messages="$(hex2binary "$messages" | $OPENSSL dgst "$hash_fn" 2>/dev/null)" - hash_messages="${hash_messages#*= }" - hkdf-expand-label "$hash_fn" "$secret" "$label" "$hash_messages" "$hash_len" - return $? -} - -# arg1: hash function -# arg2: secret -# arg3: purpose ("key" or "iv") -# arg4: length of the key -# See RFC 8446, Section 7.3 -derive-traffic-key() { - local hash_fn="$1" - local secret="$2" purpose="$3" - local -i key_length="$4" - local key - - key="$(hkdf-expand-label "$hash_fn" "$secret" "$purpose" "" "$key_length")" - [[ $? -ne 0 ]] && return 7 - tm_out "$key" - return 0 -} - -#arg1: TLS cipher -#arg2: First ClientHello, if response was a HelloRetryRequest -#arg3: HelloRetryRequest, if one was sent -#arg4: Final (or only) ClientHello -#arg5: ServerHello -create-initial-transcript() { - local cipher="$1" - local clienthello1="$2" hrr="$3" clienthello2="$4" serverhello="$5" - local hash_clienthello1 msg_transcript - - if [[ -n "$hrr" ]] && [[ "${serverhello:8:4}" == 7F12 ]]; then - msg_transcript="$clienthello1$hrr$clienthello2$serverhello" - elif [[ -n "$hrr" ]]; then - if [[ "$cipher" == *SHA256 ]]; then - hash_fn="-sha256" - hash_len=32 - elif [[ "$cipher" == *SHA384 ]]; then - hash_fn="-sha384" - hash_len=48 - else - return 1 - fi - hash_clienthello1="$(hex2binary "$clienthello1" | $OPENSSL dgst "$hash_fn" 2>/dev/null)" - hash_clienthello1="${hash_clienthello1#*= }" - msg_transcript="FE0000$(printf "%02x" $((${#hash_clienthello1}/2)))$hash_clienthello1$hrr$clienthello2$serverhello" - else - msg_transcript="$clienthello2$serverhello" - fi - tm_out "$msg_transcript" - return 0 -} - -#arg1: TLS cipher -#arg2: file containing cipher name, public key, and private key -derive-handshake-secret() { - local cipher="$1" - local tmpfile="$2" - local -i retcode - local hash_fn - local pub_file priv_file tmpfile - local early_secret derived_secret shared_secret handshake_secret - - "$HAS_PKUTIL" || return 1 - - if [[ "$cipher" == *SHA256 ]]; then - hash_fn="-sha256" - elif [[ "$cipher" == *SHA384 ]]; then - hash_fn="-sha384" - else - return 1 - fi - - pub_file="$(mktemp "$TEMPDIR/pubkey.XXXXXX")" || return 7 - awk '/-----BEGIN PUBLIC KEY/,/-----END PUBLIC KEY/ { print $0 }' \ - "$tmpfile" > "$pub_file" - [[ ! -s "$pub_file" ]] && return 1 - - priv_file="$(mktemp "$TEMPDIR/privkey.XXXXXX")" || return 7 - if grep -qe "-----BEGIN EC PARAMETERS" "$tmpfile"; then - awk '/-----BEGIN EC PARAMETERS/,/-----END EC PRIVATE KEY/ { print $0 }' \ - "$tmpfile" > "$priv_file" - else - awk '/-----BEGIN PRIVATE KEY/,/-----END PRIVATE KEY/ { print $0 }' \ - "$tmpfile" > "$priv_file" - fi - [[ ! -s "$priv_file" ]] && return 1 - - # early_secret="$(hmac "$hash_fn" "000...000" "000...000")" - case "$hash_fn" in - "-sha256") early_secret="33ad0a1c607ec03b09e6cd9893680ce210adf300aa1f2660e1b22e10f170f92a" - if [[ "${TLS_SERVER_HELLO:8:2}" == 7F ]] && [[ 0x${TLS_SERVER_HELLO:10:2} -lt 0x14 ]]; then - # "6465726976656420736563726574" = "derived secret" - # derived_secret="$(derive-secret "$hash_fn" "$early_secret" "6465726976656420736563726574" "")" - derived_secret="c1c0c36bf8fb1d1afa949fbd360e71af69a6244a4c2eaef5bbbb6442a7277d2c" - else - # "64657269766564" = "derived" - # derived_secret="$(derive-secret "$hash_fn" "$early_secret" "64657269766564" "")" - derived_secret="6f2615a108c702c5678f54fc9dbab69716c076189c48250cebeac3576c3611ba" - fi - ;; - "-sha384") early_secret="7ee8206f5570023e6dc7519eb1073bc4e791ad37b5c382aa10ba18e2357e716971f9362f2c2fe2a76bfd78dfec4ea9b5" - if [[ "${TLS_SERVER_HELLO:8:2}" == 7F ]] && [[ 0x${TLS_SERVER_HELLO:10:2} -lt 0x14 ]]; then - # "6465726976656420736563726574" = "derived secret" - # derived_secret="$(derive-secret "$hash_fn" "$early_secret" "6465726976656420736563726574" "")" - derived_secret="54c80fa05ee9e0532ce3db8ddeca37a0365683bcd3b27bdc88d2b9fdc115ca4ebc8edc1f0b72a6a0861e803fc34761ef" - else - # "64657269766564" = "derived" - # derived_secret="$(derive-secret "$hash_fn" "$early_secret" "64657269766564" "")" - derived_secret="1591dac5cbbf0330a4a84de9c753330e92d01f0a88214b4464972fd668049e93e52f2b16fad922fdc0584478428f282b" - fi - ;; - esac - - shared_secret="$($OPENSSL pkeyutl -derive -inkey "$priv_file" -peerkey "$pub_file" 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - rm "$pub_file" "$priv_file" - - # For draft 18 use $early_secret rather than $derived_secret. - if [[ "${TLS_SERVER_HELLO:8:4}" == "7F12" ]]; then - handshake_secret="$(hmac "$hash_fn" "$early_secret" "${shared_secret%%[!0-9A-F]*}")" - else - handshake_secret="$(hmac "$hash_fn" "$derived_secret" "${shared_secret%%[!0-9A-F]*}")" - fi - [[ $? -ne 0 ]] && return 7 - - tm_out "$handshake_secret" - return 0 -} - -# arg1: TLS cipher -# arg2: handshake secret -# arg3: transcript -# arg4: "client" or "server" -derive-handshake-traffic-keys() { - local cipher="$1" handshake_secret="$2" transcript="$3" - local sender="$4" - local hash_fn - local -i hash_len key_len - local handshake_traffic_secret label key iv finished="0000" - - if [[ "$cipher" == *SHA256 ]]; then - hash_fn="-sha256" - hash_len=32 - elif [[ "$cipher" == *SHA384 ]]; then - hash_fn="-sha384" - hash_len=48 - else - return 1 - fi - if [[ "$cipher" == *AES_128* ]]; then - key_len=16 - elif [[ "$cipher" == *AES_256* ]] || [[ "$cipher" == *CHACHA20_POLY1305* ]]; then - key_len=32 - else - return 1 - fi - - if [[ "${TLS_SERVER_HELLO:8:2}" == 7F ]] && [[ 0x${TLS_SERVER_HELLO:10:2} -lt 0x14 ]]; then - if [[ "$sender" == server ]]; then - # "7365727665722068616e647368616b65207472616666696320736563726574" = "server handshake traffic secret" - label="7365727665722068616e647368616b65207472616666696320736563726574" - else - # "636c69656e742068616e647368616b65207472616666696320736563726574" = "client handshake traffic secret" - label="636c69656e742068616e647368616b65207472616666696320736563726574" - fi - elif [[ "$sender" == server ]]; then - # "732068732074726166666963" = "s hs traffic" - label="732068732074726166666963" - else - # "632068732074726166666963" = "c hs traffic" - label="632068732074726166666963" - fi - handshake_traffic_secret="$(derive-secret "$hash_fn" "$handshake_secret" "$label" "$transcript")" - [[ $? -ne 0 ]] && return 7 - - # "6b6579" = "key" - key="$(derive-traffic-key "$hash_fn" "$handshake_traffic_secret" "6b6579" "$key_len")" - [[ $? -ne 0 ]] && return 1 - # "6976" = "iv" - iv="$(derive-traffic-key "$hash_fn" "$handshake_traffic_secret" "6976" "12")" - [[ $? -ne 0 ]] && return 1 - if [[ $DEBUG -ge 1 ]] || [[ "$sender" == client ]]; then - # "66696e6973686564" = "finished" - finished="$(derive-traffic-key "$hash_fn" "$handshake_traffic_secret" "66696e6973686564" "$hash_len")" - [[ $? -ne 0 ]] && return 1 - fi - tm_out "$key $iv $finished" -} - -#arg1: TLS cipher -#arg2: handshake secret -derive-master-secret() { - local cipher="$1" - local handshake_secret="$2" - local -i retcode - local hash_fn - local derived_secret zeros master_secret - - if [[ "$cipher" == *SHA256 ]]; then - hash_fn="-sha256" - zeros="0000000000000000000000000000000000000000000000000000000000000000" - elif [[ "$cipher" == *SHA384 ]]; then - hash_fn="-sha384" - zeros="000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - else - return 1 - fi - - if [[ "${TLS_SERVER_HELLO:8:4}" == 7F12 ]]; then - derived_secret="$handshake_secret" - elif [[ "${TLS_SERVER_HELLO:8:2}" == 7F ]] && [[ 0x${TLS_SERVER_HELLO:10:2} -lt 0x14 ]]; then - derived_secret="$(derive-secret "$hash_fn" "$handshake_secret" "6465726976656420736563726574" "")" - else - derived_secret="$(derive-secret "$hash_fn" "$handshake_secret" "64657269766564" "")" - fi - master_secret="$(hmac "$hash_fn" "$derived_secret" "$zeros")" - [[ $? -ne 0 ]] && return 7 - - tm_out "$master_secret" - return 0 -} - -# arg1: TLS cipher -# arg2: master secret -# arg3: transcript -# arg4: "client" or "server" -derive-application-traffic-keys() { - local cipher="$1" master_secret="$2" transcript="$3" - local sender="$4" - local hash_fn - local -i key_len - local application_traffic_secret_0 label key iv - - if [[ "$cipher" == *SHA256 ]]; then - hash_fn="-sha256" - elif [[ "$cipher" == *SHA384 ]]; then - hash_fn="-sha384" - else - return 1 - fi - if [[ "$cipher" == *AES_128* ]]; then - key_len=16 - elif [[ "$cipher" == *AES_256* ]] || [[ "$cipher" == *CHACHA20_POLY1305* ]]; then - key_len=32 - else - return 1 - fi - - if [[ "${TLS_SERVER_HELLO:8:2}" == 7F ]] && [[ 0x${TLS_SERVER_HELLO:10:2} -lt 0x14 ]]; then - if [[ "$sender" == server ]]; then - # "736572766572206170706c69636174696f6e207472616666696320736563726574" = "server application traffic secret" - label="736572766572206170706c69636174696f6e207472616666696320736563726574" - else - # "636c69656e74206170706c69636174696f6e207472616666696320736563726574" = "client application traffic secret" - label="636c69656e74206170706c69636174696f6e207472616666696320736563726574" - fi - elif [[ "$sender" == server ]]; then - # "732061702074726166666963" = "s hs traffic" - label="732061702074726166666963" - else - # "632061702074726166666963" = "c hs traffic" - label="632061702074726166666963" - fi - application_traffic_secret_0="$(derive-secret "$hash_fn" "$master_secret" "$label" "$transcript")" - [[ $? -ne 0 ]] && return 7 - - # "6b6579" = "key" - key="$(derive-traffic-key "$hash_fn" "$application_traffic_secret_0" "6b6579" "$key_len")" - [[ $? -ne 0 ]] && return 1 - # "6976" = "iv" - iv="$(derive-traffic-key "$hash_fn" "$application_traffic_secret_0" "6976" "12")" - [[ $? -ne 0 ]] && return 1 - tm_out "$key $iv" -} - -# See RFC 8439, Section 2.1 -chacha20_Qround() { - local -i a="0x$1" - local -i b="0x$2" - local -i c="0x$3" - local -i d="0x$4" - local -i x y - - a=$(((a+b) & 0xffffffff)) - d=$((d^a)) - # rotate d left 16 bits - x=$((d & 0xffff0000)) - x=$((x >> 16)) - y=$((d & 0x0000ffff)) - y=$((y << 16)) - d=$((x | y)) - - c=$(((c+d) & 0xffffffff)) - b=$((b^c)) - # rotate b left 12 bits - x=$((b & 0xfff00000)) - x=$((x >> 20)) - y=$((b & 0x000fffff)) - y=$((y << 12)) - b=$((x | y)) - - a=$(((a+b) & 0xffffffff)) - d=$((d^a)) - # rotate d left 8 bits - x=$((d & 0xff000000)) - x=$((x >> 24)) - y=$((d & 0x00ffffff)) - y=$((y << 8)) - d=$((x | y)) - - c=$(((c+d) & 0xffffffff)) - b=$((b^c)) - # rotate b left 7 bits - x=$((b & 0xfe000000)) - x=$((x >> 25)) - y=$((b & 0x01ffffff)) - y=$((y << 7)) - b=$((x | y)) - - tm_out "$(printf "%X" $a) $(printf "%X" $b) $(printf "%X" $c) $(printf "%X" $d)" - return 0 -} - -# See RFC 8439, Section 2.3.1 -chacha20_inner_block() { - local s0="$1" s1="$2" s2="$3" s3="$4" - local s4="$5" s5="$6" s6="$7" s7="$8" - local s8="$9" s9="${10}" s10="${11}" s11="${12}" - local s12="${13}" s13="${14}" s14="${15}" s15="${16}" - local res - - res="$(chacha20_Qround "$s0" "$s4" "$s8" "$s12")" - read -r s0 s4 s8 s12 <<< "$res" - res="$(chacha20_Qround "$s1" "$s5" "$s9" "$s13")" - read -r s1 s5 s9 s13 <<< "$res" - res="$(chacha20_Qround "$s2" "$s6" "$s10" "$s14")" - read -r s2 s6 s10 s14 <<< "$res" - res="$(chacha20_Qround "$s3" "$s7" "$s11" "$s15")" - read -r s3 s7 s11 s15 <<< "$res" - res="$(chacha20_Qround "$s0" "$s5" "$s10" "$s15")" - read -r s0 s5 s10 s15 <<< "$res" - res="$(chacha20_Qround "$s1" "$s6" "$s11" "$s12")" - read -r s1 s6 s11 s12 <<< "$res" - res="$(chacha20_Qround "$s2" "$s7" "$s8" "$s13")" - read -r s2 s7 s8 s13 <<< "$res" - res="$(chacha20_Qround "$s3" "$s4" "$s9" "$s14")" - read -r s3 s4 s9 s14 <<< "$res" - - tm_out "$s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9 $s10 $s11 $s12 $s13 $s14 $s15" - return 0 -} - -# See RFC 8439, Sections 2.3 and 2.3.1 -chacha20_block() { - local key="$1" - local counter="$2" - local nonce="$3" - local s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 - local ws0 ws1 ws2 ws3 ws4 ws5 ws6 ws7 ws8 ws9 ws10 ws11 ws12 ws13 ws14 ws15 - local working_state - local -i i - - # create the state variable - s0="61707865"; s1="3320646e"; s2="79622d32"; s3="6b206574" - s4="${key:6:2}${key:4:2}${key:2:2}${key:0:2}" - s5="${key:14:2}${key:12:2}${key:10:2}${key:8:2}" - s6="${key:22:2}${key:20:2}${key:18:2}${key:16:2}" - s7="${key:30:2}${key:28:2}${key:26:2}${key:24:2}" - s8="${key:38:2}${key:36:2}${key:34:2}${key:32:2}" - s9="${key:46:2}${key:44:2}${key:42:2}${key:40:2}" - s10="${key:54:2}${key:52:2}${key:50:2}${key:48:2}" - s11="${key:62:2}${key:60:2}${key:58:2}${key:56:2}" - s12="$counter" - s13="${nonce:6:2}${nonce:4:2}${nonce:2:2}${nonce:0:2}" - s14="${nonce:14:2}${nonce:12:2}${nonce:10:2}${nonce:8:2}" - s15="${nonce:22:2}${nonce:20:2}${nonce:18:2}${nonce:16:2}" - - # Initialize working_state to state - working_state="$s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9 $s10 $s11 $s12 $s13 $s14 $s15" - - # compute the 20 rounds (10 calls to inner block function, each of which - # performs 8 quarter rounds). - for (( i=0 ; i < 10; i++ )); do - working_state="$(chacha20_inner_block $working_state)" - done - read -r ws0 ws1 ws2 ws3 ws4 ws5 ws6 ws7 ws8 ws9 ws10 ws11 ws12 ws13 ws14 ws15 <<< "$working_state" - - # Add working state to state - s0="$(printf "%08X" $(((0x$s0+0x$ws0) & 0xffffffff)))" - s1="$(printf "%08X" $(((0x$s1+0x$ws1) & 0xffffffff)))" - s2="$(printf "%08X" $(((0x$s2+0x$ws2) & 0xffffffff)))" - s3="$(printf "%08X" $(((0x$s3+0x$ws3) & 0xffffffff)))" - s4="$(printf "%08X" $(((0x$s4+0x$ws4) & 0xffffffff)))" - s5="$(printf "%08X" $(((0x$s5+0x$ws5) & 0xffffffff)))" - s6="$(printf "%08X" $(((0x$s6+0x$ws6) & 0xffffffff)))" - s7="$(printf "%08X" $(((0x$s7+0x$ws7) & 0xffffffff)))" - s8="$(printf "%08X" $(((0x$s8+0x$ws8) & 0xffffffff)))" - s9="$(printf "%08X" $(((0x$s9+0x$ws9) & 0xffffffff)))" - s10="$(printf "%08X" $(((0x$s10+0x$ws10) & 0xffffffff)))" - s11="$(printf "%08X" $(((0x$s11+0x$ws11) & 0xffffffff)))" - s12="$(printf "%08X" $(((0x$s12+0x$ws12) & 0xffffffff)))" - s13="$(printf "%08X" $(((0x$s13+0x$ws13) & 0xffffffff)))" - s14="$(printf "%08X" $(((0x$s14+0x$ws14) & 0xffffffff)))" - s15="$(printf "%08X" $(((0x$s15+0x$ws15) & 0xffffffff)))" - - # serialize the state - s0="${s0:6:2}${s0:4:2}${s0:2:2}${s0:0:2}" - s1="${s1:6:2}${s1:4:2}${s1:2:2}${s1:0:2}" - s2="${s2:6:2}${s2:4:2}${s2:2:2}${s2:0:2}" - s3="${s3:6:2}${s3:4:2}${s3:2:2}${s3:0:2}" - s4="${s4:6:2}${s4:4:2}${s4:2:2}${s4:0:2}" - s5="${s5:6:2}${s5:4:2}${s5:2:2}${s5:0:2}" - s6="${s6:6:2}${s6:4:2}${s6:2:2}${s6:0:2}" - s7="${s7:6:2}${s7:4:2}${s7:2:2}${s7:0:2}" - s8="${s8:6:2}${s8:4:2}${s8:2:2}${s8:0:2}" - s9="${s9:6:2}${s9:4:2}${s9:2:2}${s9:0:2}" - s10="${s10:6:2}${s10:4:2}${s10:2:2}${s10:0:2}" - s11="${s11:6:2}${s11:4:2}${s11:2:2}${s11:0:2}" - s12="${s12:6:2}${s12:4:2}${s12:2:2}${s12:0:2}" - s13="${s13:6:2}${s13:4:2}${s13:2:2}${s13:0:2}" - s14="${s14:6:2}${s14:4:2}${s14:2:2}${s14:0:2}" - s15="${s15:6:2}${s15:4:2}${s15:2:2}${s15:0:2}" - - tm_out "$s0$s1$s2$s3$s4$s5$s6$s7$s8$s9$s10$s11$s12$s13$s14$s15" - return 0 -} - -# See RFC 8439, Section 2.4 -chacha20() { - local key="$1" - local -i counter=1 - local nonce="$2" - local ciphertext="$3" - local -i i ciphertext_len num_blocks mod_check - local -i i1 i2 i3 i4 i5 i6 i7 i8 i9 i10 i11 i12 i13 i14 i15 i16 - local keystream plaintext="" - - if "$HAS_CHACHA20"; then - plaintext="$(hex2binary "$ciphertext" | \ - $OPENSSL enc -chacha20 -K "$key" -iv "01000000$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - tm_out "$(strip_spaces "$plaintext")" - return 0 - fi - - ciphertext_len=${#ciphertext} - num_blocks=$ciphertext_len/128 - - for (( i=0; i < num_blocks; i++)); do - i1=$((128*i)); i2=$((i1+8)); i3=$((i1+16)); i4=$((i1+24)); i5=$((i1+32)); i6=$((i1+40)); i7=$((i1+48)); i8=$((i1+56)) - i9=$((i1+64)); i10=$((i1+72)); i11=$((i1+80)); i12=$((i1+88)); i13=$((i1+96)); i14=$((i1+104)); i15=$((i1+112)); i16=$((i1+120)) - keystream="$(chacha20_block "$key" "$(printf "%08X" $counter)" "$nonce")" - plaintext+="$(printf "%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X" \ - "$((0x${ciphertext:i1:8} ^ 0x${keystream:0:8}))" \ - "$((0x${ciphertext:i2:8} ^ 0x${keystream:8:8}))" \ - "$((0x${ciphertext:i3:8} ^ 0x${keystream:16:8}))" \ - "$((0x${ciphertext:i4:8} ^ 0x${keystream:24:8}))" \ - "$((0x${ciphertext:i5:8} ^ 0x${keystream:32:8}))" \ - "$((0x${ciphertext:i6:8} ^ 0x${keystream:40:8}))" \ - "$((0x${ciphertext:i7:8} ^ 0x${keystream:48:8}))" \ - "$((0x${ciphertext:i8:8} ^ 0x${keystream:56:8}))" \ - "$((0x${ciphertext:i9:8} ^ 0x${keystream:64:8}))" \ - "$((0x${ciphertext:i10:8} ^ 0x${keystream:72:8}))" \ - "$((0x${ciphertext:i11:8} ^ 0x${keystream:80:8}))" \ - "$((0x${ciphertext:i12:8} ^ 0x${keystream:88:8}))" \ - "$((0x${ciphertext:i13:8} ^ 0x${keystream:96:8}))" \ - "$((0x${ciphertext:i14:8} ^ 0x${keystream:104:8}))" \ - "$((0x${ciphertext:i15:8} ^ 0x${keystream:112:8}))" \ - "$((0x${ciphertext:i16:8} ^ 0x${keystream:120:8}))")" - counter+=1 - done - - mod_check=$ciphertext_len%128 - if [[ $mod_check -ne 0 ]]; then - keystream="$(chacha20_block "$key" "$(printf "%08X" $counter)" "$nonce")" - i1=$((128*num_blocks)) - for (( i=0; i < mod_check; i+=2 )); do - plaintext+="$(printf "%02X" "$((0x${ciphertext:i1:2} ^ 0x${keystream:i:2}))")" - i1+=2 - done - fi - tm_out "$plaintext" - return 0 -} - -# Implement U8to32 from https://github.com/floodyberry/poly1305-donna/blob/master/poly1305-donna-32.h -# Used to decode value encoded as 32-bit little-endian integer -u8to32() { - local p="$1" - - tm_out "0x${p:6:2}${p:4:2}${p:2:2}${p:0:2}" - return 0 -} - -# Implement U32to8 from https://github.com/floodyberry/poly1305-donna/blob/master/poly1305-donna-32.h -# Used to encode value as 32-bit little-endian integer -u32to8() { - local -i v="$1" - local p - - v=$((v & 0xffffffff)) - p="$(printf "%08X" $v)" - tm_out "${p:6:2}${p:4:2}${p:2:2}${p:0:2}" - return 0 -} - -# Used to encode value as 64-bit little-endian integer -u64to8() { - local -i v="$1" - local p - - p="$(printf "%016X" "$v")" - tm_out "${p:14:2}${p:12:2}${p:10:2}${p:8:2}${p:6:2}${p:4:2}${p:2:2}${p:0:2}" - return 0 -} - - -# arg1: 32-byte key -# arg2: message to be authenticated -# See RFC 8439, Section 2.5 -# Implementation based on https://github.com/floodyberry/poly1305-donna -poly1305_mac() { - local key="$1" nonce="$2" ciphertext="$3" aad="$4" - local mac_key msg - local -i ciphertext_len aad_len - local -i bytes - local -i r0 r1 r2 r3 r4 - local -i h0=0 h1=0 h2=0 h3=0 h4=0 - local -i pad0 pad1 pad2 pad3 - local -i s1 s2 s3 s4 - local -i d0 d1 d2 d3 d4 - local -i g0 g1 g2 g3 g4 - local -i i c f blocksize hibit - local padding="00000000000000000000000000000000" - - # poly1305_key_gen - RFC 8439, Section 2.6 - # The MAC key is actually just the first 64 characters (32 bytes) of the - # output of the chacha20_block function. However, there is no need to - # truncate the key, since the code below will ignore all but the first - # 64 characters. - mac_key="$(chacha20_block "$key" "00000000" "$nonce")" - - # Construct message to be authenticated. RFC 8439, Section 2.8 - msg="$aad" - aad_len=$((${#aad}/2)) - bytes=$(( aad_len % 16 )) - [[ $bytes -ne 0 ]] && msg+="${padding:0:$((2*(16-bytes)))}" - msg+="$ciphertext" - ciphertext_len=$((${#ciphertext}/2)) - bytes=$(( ciphertext_len % 16 )) - [[ $bytes -ne 0 ]] && msg+="${padding:0:$((2*(16-bytes)))}" - msg+="$(u64to8 $aad_len)$(u64to8 $ciphertext_len)" - bytes="${#msg}" - - # poly1305_init - r0=$(( $(u8to32 "${mac_key:0:8}") & 0x3ffffff )) - r1=$(( ($(u8to32 "${mac_key:6:8}") >> 2) & 0x3ffff03 )) - r2=$(( ($(u8to32 "${mac_key:12:8}") >> 4) & 0x3ffc0ff )) - r3=$(( ($(u8to32 "${mac_key:18:8}") >> 6) & 0x3f03fff )) - r4=$(( ($(u8to32 "${mac_key:24:8}") >> 8) & 0x00fffff )) - - s1=$((r1*5)) - s2=$((r2*5)) - s3=$((r3*5)) - s4=$((r4*5)) - - pad0=$(u8to32 "${mac_key:32:8}") - pad1=$(u8to32 "${mac_key:40:8}") - pad2=$(u8to32 "${mac_key:48:8}") - pad3=$(u8to32 "${mac_key:56:8}") - - # poly1305_update - for (( 1 ; bytes > 0; bytes=bytes-blocksize )); do - if [[ $bytes -ge 32 ]]; then - blocksize=32 - hibit=0x1000000 - else - blocksize=$bytes - hibit=0 - msg+="01${padding:0:$((30-bytes))}" - fi - h0+=$(( $(u8to32 "${msg:0:8}") & 0x3ffffff )) - h1+=$(( ($(u8to32 "${msg:6:8}") >> 2) & 0x3ffffff )) - h2+=$(( ($(u8to32 "${msg:12:8}") >> 4) & 0x3ffffff )) - h3+=$(( ($(u8to32 "${msg:18:8}") >> 6) & 0x3ffffff )) - h4+=$(( (($(u8to32 "${msg:24:8}") >> 8) & 0xffffff) | hibit )) - - d0=$(( h0*r0 + h1*s4 + h2*s3 + h3*s2 + h4*s1 )) - d1=$(( h0*r1 + h1*r0 + h2*s4 + h3*s3 + h4*s2 )) - d2=$(( h0*r2 + h1*r1 + h2*r0 + h3*s4 + h4*s3 )) - d3=$(( h0*r3 + h1*r2 + h2*r1 + h3*r0 + h4*s4 )) - d4=$(( h0*r4 + h1*r3 + h2*r2 + h3*r1 + h4*r0 )) - - c=$(( (d0 >> 26) & 0x3fffffffff )); h0=$(( d0 & 0x3ffffff )) - d1+=$c; c=$(( (d1 >> 26) & 0x3fffffffff )); h1=$(( d1 & 0x3ffffff )) - d2+=$c; c=$(( (d2 >> 26) & 0x3fffffffff )); h2=$(( d2 & 0x3ffffff )) - d3+=$c; c=$(( (d3 >> 26) & 0x3fffffffff )); h3=$(( d3 & 0x3ffffff )) - d4+=$c; c=$(( (d4 >> 26) & 0x3fffffffff )); h4=$(( d4 & 0x3ffffff )) - h0+=$((c*5)); c=$(( (h0 >> 26) & 0x3fffffffff )); h0=$(( h0 & 0x3ffffff )) - h1+=$c - - msg="${msg:32}" - done - - # poly1305_finish - c=$(( (h0 >> 26) & 0x3f )); h1=$(( h1 & 0x3ffffff )) - h2+=$c; c=$(( (h2 >> 26) & 0x3f )); h2=$(( h2 & 0x3ffffff )) - h3+=$c; c=$(( (h3 >> 26) & 0x3f )); h3=$(( h3 & 0x3ffffff )) - h4+=$c; c=$(( (h4 >> 26) & 0x3f )); h4=$(( h4 & 0x3ffffff )) - h0+=$((c*5)); c=$(( (h0 >> 26) & 0x3f )); h0=$(( h0 & 0x3ffffff )) - h1+=$c - - g0=$((h0+5)); c=$(( (g0 >> 26) & 0x3f )); g0=$(( g0 & 0x3ffffff )) - g1=$((h1+c)); c=$(( (g1 >> 26) & 0x3f )); g1=$(( g1 & 0x3ffffff )) - g2=$((h2+c)); c=$(( (g2 >> 26) & 0x3f )); g2=$(( g2 & 0x3ffffff )) - g3=$((h3+c)); c=$(( (g3 >> 26) & 0x3f )); g3=$(( g3 & 0x3ffffff )) - g4=$((h4+c-0x4000000)) - - if [[ $((g4 & 0x8000000000000000)) -eq 0 ]]; then - h0=$g0; h1=$g1; h2=$g2; h3=$g3; h4=$g4 - fi - h0=$(( ( h0 | (h1 << 26)) & 0xffffffff)) - h1=$(( ((h1 >> 6) | (h2 << 20)) & 0xffffffff)) - h2=$(( ((h2 >> 12) | (h3 << 14)) & 0xffffffff)) - h3=$(( ((h3 >> 18) | (h4 << 8)) & 0xffffffff)) - - f=$(( h0+pad0 )); h0=$f - f=$(( h1+pad1+(f>>32) )); h1=$f - f=$(( h2+pad2+(f>>32) )); h2=$f - f=$(( h3+pad3+(f>>32) )); h3=$f - - tm_out "$(u32to8 $h0)$(u32to8 $h1)$(u32to8 $h2)$(u32to8 $h3)" - return 0 -} - -# arg1: key -# arg2: nonce (must be 96 bits in length) -# arg3: ciphertext -# arg4: additional authenticated data -# arg5: expected tag -# arg6: true if authentication tag should be checked. false otherwise. -chacha20_aead_decrypt() { - local key="$1" nonce="$2" ciphertext="$3" aad="$4" expected_tag="$(toupper "$5")" - local compute_tag="$6" - local plaintext computed_tag - - plaintext="$(chacha20 "$key" "$nonce" "$ciphertext")" - [[ $? -ne 0 ]] && return 7 - - if "$compute_tag"; then - computed_tag="$(poly1305_mac "$key" "$nonce" "$ciphertext" "$aad")" - [[ $? -ne 0 ]] && return 7 - [[ "$computed_tag" == $expected_tag ]] || return 7 - fi - - tm_out "$plaintext" - return 0 -} - -# arg1: key -# arg2: nonce (must be 96 bits in length) -# arg3: plaintext -# arg4: additional authenticated data -chacha20_aead_encrypt() { - local key="$1" nonce="$2" plaintext="$3" aad="$4" - local ciphertext computed_tag - - ciphertext="$(chacha20 "$key" "$nonce" "$plaintext")" - [[ $? -ne 0 ]] && return 7 - - computed_tag="$(poly1305_mac "$key" "$nonce" "$ciphertext" "$aad")" - [[ $? -ne 0 ]] && return 7 - - tm_out "$ciphertext $computed_tag" - return 0 -} - -# arg1: nonce (must be 96 bits) -# arg2: number of blocks needed for plaintext/ciphertext -# Generate the sequence of counter blocks, which are to be encrypted and then -# XORed with either the plaintext or the ciphertext. -# See Section 6.1, Section 6.2, and Appendix A.3 of NIST SP 800-38C and -# Section 5.3 of RFC 5116. -generate-ccm-counter-blocks() { - local ctr="02${1}000000" ctr_msb blocks="" - local -i i ctr_lsb n="$2" - - ctr_msb="${ctr:0:24}" - ctr_lsb=0x${ctr:24:8} - - for (( i=0; i <= n; i+=1 )); do - blocks+="${ctr_msb}$(printf "%08X" "$ctr_lsb")" - ctr_lsb+=1 - done - hex2binary "$blocks" - return 0 -} - -# arg1: an OpenSSL ecb cipher (e.g., -aes-128-ecb) -# arg2: key -# arg3: iv (must be 96 bits in length) -# arg4: additional authenticated data -# arg5: plaintext -# arg6: tag length (must be 16 or 32) -# Compute the CCM authentication tag -ccm-compute-tag() { - local cipher="$1" key="$2" iv="$3" aad="$4" plaintext="$5" - local -i tag_len="$6" - local b tag - local -i i aad_len plaintext_len final_block_len nr_blocks - local padding_bytes="00000000000000000000000000000000" - - aad_len=$((${#aad}/2)) - plaintext_len=$((${#plaintext}/2)) - - # Apply the formatting function to create b=B0B1B2... as in - # Appendix A.2 of NIST SP 800-38C. - - # The first block consists of the flags, nonce, and length of plaintext - # See Section 5.3 of RFC 5116 for value of q. - if [[ $aad_len -ne 0 ]]; then - if [[ $tag_len -eq 16 ]]; then - b="5A${iv}$(printf "%06X" $plaintext_len)" - else - b="7A${iv}$(printf "%06X" $plaintext_len)" - fi - elif [[ $tag_len -eq 16 ]]; then - b="1A${iv}$(printf "%06X" $plaintext_len)" - else - b="3A${iv}$(printf "%06X" $plaintext_len)" - fi - - # Next comes any additional authenticated data - if [[ $aad_len -ne 0 ]]; then - if [[ $aad_len -lt 0xFF00 ]]; then - b+="$(printf "%04X" $aad_len)$aad" - final_block_len=$(( (aad_len+2) % 16 )) - elif [[ $aad_len -lt 0x100000000 ]]; then - b+="FFFE$(printf "%08X" $aad_len)$aad" - final_block_len=$(( (aad_len+6) % 16 )) - else - # AES-CCM supports lengths up to 2^64, but there doesn't - # seem to be any reason to try to support such lengths. - return 7 - fi - # Add padding to complete block - [[ $final_block_len -ne 0 ]] && b+="${padding_bytes:0:$((2*(16-final_block_len)))}" - fi - - # Finally add the plaintext and any padding needed to complete block - b+="$plaintext" - final_block_len=$((plaintext_len % 16)) - [[ $final_block_len -ne 0 ]] && b+="${padding_bytes:0:$((2*(16-final_block_len)))}" - - # Compute the authentication tag as described in - # Sections 6.1 and 6.2 of NIST SP 800-38C. - nr_blocks=$((${#b}/32)) - tag="${b:0:32}" - for (( i=0; i < nr_blocks; i++ )); do - # XOR current block with previous block and then encrypt - [[ $i -ne 0 ]] && - tag="$(printf "%08X%08X%08X%08X" "$((0x${b:0:8} ^ 0x${tag:0:8}))" "$((0x${b:8:8} ^ 0x${tag:8:8}))" "$((0x${b:16:8} ^ 0x${tag:16:8}))" "$((0x${b:24:8} ^ 0x${tag:24:8}))")" - - tag="$(hex2binary "$tag" | $OPENSSL enc "$cipher" -K "$key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - b="${b:32}" - done - - tm_out "${tag:0:tag_len}" - return 0 -} - -# arg1: AES-CCM TLS cipher -# arg2: key -# arg3: nonce (must be 96 bits in length) -# arg4: ciphertext -# arg5: additional authenticated data -# arg6: expected tag (must be 16 or 32 characters) -# arg7: true if authentication tag should be checked. false otherwise. -# See Section 6.2 of NIST SP 800-38C -ccm-decrypt() { - local cipher="$1" key="$2" nonce="$3" ciphertext="$4" aad="$5" enciphered_expected_tag="$6" - local compute_tag="$7" - local plaintext="" expected_tag computed_tag - local -i i i1 i2 i3 i4 tag_len - local -i ciphertext_len n mod_check - local s s0 - - [[ ${#nonce} -ne 24 ]] && return 7 - - case "$cipher" in - *AES_128*) cipher="-aes-128-ecb" ;; - *AES_256*) cipher="-aes-256-ecb" ;; - *) return 7 - esac - - ciphertext_len=${#ciphertext} - n=$((ciphertext_len/32)) - mod_check=$((ciphertext_len%32)) - [[ $mod_check -ne 0 ]] && n+=1 - - # generate keystream - s="$(generate-ccm-counter-blocks "$nonce" "$n" | $OPENSSL enc "$cipher" -K "$key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - - # The first 16-bytes of the keystream ($s) are used to decrypt the - # authentication tag and the remaining bytes are used to decrypt the - # ciphertext. - s0="${s:0:32}" - s="${s:32}" - - # XOR the ciphertext with the keystream ($s). For efficiency, work in blocks - # of 16 bytes at a time (but with each XOR operation working on 32 bits. - [[ $mod_check -ne 0 ]] && n=$((n-1)) - for (( i=0; i < n; i++ )); do - i1=$((32*i)); i2=$((i1+8)); i3=$((i1+16)); i4=$((i1+24)) - plaintext+="$(printf "%08X%08X%08X%08X" "$((0x${ciphertext:i1:8} ^ 0x${s:i1:8}))" "$((0x${ciphertext:i2:8} ^ 0x${s:i2:8}))" "$((0x${ciphertext:i3:8} ^ 0x${s:i3:8}))" "$((0x${ciphertext:i4:8} ^ 0x${s:i4:8}))")" - done - - # If the length of the ciphertext is not an even multiple of 16 bytes, then handle the final incomplete block. - if [[ $mod_check -ne 0 ]]; then - i1=$((32*n)) - for (( i=0; i < mod_check; i+=2 )); do - plaintext+="$(printf "%02X" "$((0x${ciphertext:i1:2} ^ 0x${s:i1:2}))")" - i1+=2 - done - fi - - if "$compute_tag"; then - tag_len=${#enciphered_expected_tag} - - # Decrypt the authentication tag that was provided with the message - if [[ $tag_len -eq 16 ]]; then - expected_tag="$(printf "%08X%08X" "$((0x${enciphered_expected_tag:0:8} ^ 0x${s0:0:8}))" "$((0x${enciphered_expected_tag:8:8} ^ 0x${s0:8:8}))")" - elif [[ $tag_len -eq 32 ]]; then - expected_tag="$(printf "%08X%08X%08X%08X" "$((0x${enciphered_expected_tag:0:8} ^ 0x${s0:0:8}))" "$((0x${enciphered_expected_tag:8:8} ^ 0x${s0:8:8}))" "$((0x${enciphered_expected_tag:16:8} ^ 0x${s0:16:8}))" "$((0x${enciphered_expected_tag:24:8} ^ 0x${s0:24:8}))")" - else - return 7 - fi - - # obtain the actual authentication tag for the decrypted message - computed_tag="$(ccm-compute-tag "$cipher" "$key" "$nonce" "$aad" "$plaintext" "$tag_len")" - [[ $? -ne 0 ]] && return 7 - fi - - if ! "$compute_tag" || [[ "$computed_tag" == $expected_tag ]]; then - tm_out "$plaintext" - return 0 - else - return 7 - fi -} - -# arg1: AES-CCM TLS cipher -# arg2: key -# arg3: nonce (must be 96 bits in length) -# arg4: plaintext -# arg5: additional authenticated data -# See Section 6.1 of NIST SP 800-38C -ccm-encrypt() { - local cipher="$1" key="$2" nonce="$3" plaintext="$4" aad="$5" - local -i tag_len - local ossl_cipher="-aes-128-ecb" - local ciphertext="" tag encrypted_tag - local -i i i1 i2 i3 i4 - local -i plaintext_len n mod_check - local s s0 - - [[ ${#nonce} -ne 24 ]] && return 7 - - case "$cipher" in - TLS_AES_128_CCM_SHA256) tag_len=32 ;; - TLS_AES_128_CCM_8_SHA256) tag_len=16 ;; - *) return 7 - esac - - # compute the authentication tag - tag="$(ccm-compute-tag "$ossl_cipher" "$key" "$nonce" "$aad" "$plaintext" "$tag_len")" - [[ $? -ne 0 ]] && return 7 - - plaintext_len=${#plaintext} - n=$((plaintext_len/32)) - mod_check=$((plaintext_len%32)) - [[ $mod_check -ne 0 ]] && n+=1 - - # generate keystream - s="$(generate-ccm-counter-blocks "$nonce" "$n" | $OPENSSL enc "$ossl_cipher" -K "$key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - - # encrypt the authentication tag using the first 16 bytes of the keystrem ($s) - if [[ $tag_len -eq 16 ]]; then - encrypted_tag="$(printf "%08X%08X" "$((0x${tag:0:8} ^ 0x${s:0:8}))" "$((0x${tag:8:8} ^ 0x${s:8:8}))")" - elif [[ $tag_len -eq 32 ]]; then - encrypted_tag="$(printf "%08X%08X%08X%08X" "$((0x${tag:0:8} ^ 0x${s:0:8}))" "$((0x${tag:8:8} ^ 0x${s:8:8}))" "$((0x${tag:16:8} ^ 0x${s:16:8}))" "$((0x${tag:24:8} ^ 0x${s:24:8}))")" - else - return 7 - fi - - # XOR the plaintext with the keystream ($s). For efficiency, work in blocks - # of 16 bytes at a time (but with each XOR operation working on 32 bits. - s="${s:32}" - [[ $mod_check -ne 0 ]] && n=$((n-1)) - for (( i=0; i < n; i++ )); do - i1=$((32*i)); i2=$((i1+8)); i3=$((i1+16)); i4=$((i1+24)) - ciphertext+="$(printf "%08X%08X%08X%08X" "$((0x${plaintext:i1:8} ^ 0x${s:i1:8}))" "$((0x${plaintext:i2:8} ^ 0x${s:i2:8}))" "$((0x${plaintext:i3:8} ^ 0x${s:i3:8}))" "$((0x${plaintext:i4:8} ^ 0x${s:i4:8}))")" - done - # If the length of the plaintext is not an even multiple of 16 bytes, then handle the final incomplete block. - if [[ $mod_check -ne 0 ]]; then - i1=$((32*n)) - for (( i=0; i < mod_check; i+=2 )); do - ciphertext+="$(printf "%02X" "$((0x${plaintext:i1:2} ^ 0x${s:i1:2}))")" - i1+=2 - done - fi - tm_out "$ciphertext$encrypted_tag" - return 0 -} - -# This function is based on gcm_mult in https://github.com/mko-x/SharedAES-GCM -# args 1-16: HL from gcm_ctx -# args 17-32: HH from gcm_ctx -# args 33-48: x - the input vector -gcm_mult() { - local -a gcm_ctx_hl=( "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "${10}" "${11}" "${12}" "${13}" "${14}" "${15}" "${16}" ) - local -a gcm_ctx_hh=( "${17}" "${18}" "${19}" "${20}" "${21}" "${22}" "${23}" "${24}" "${25}" "${26}" "${27}" "${28}" "${29}" "${30}" "${31}" "${32}" ) - local -a x=( "${33}" "${34}" "${35}" "${36}" "${37}" "${38}" "${39}" "${40}" "${41}" "${42}" "${43}" "${44}" "${45}" "${46}" "${47}" "${48}" ) - local output - local -i i lo hi rem zh zl - local -r -a -i last4=(0x0000 0x1c20 0x3840 0x2460 0x7080 0x6ca0 0x48c0 0x54e0 0xe100 0xfd20 0xd940 0xc560 0x9180 0x8da0 0xa9c0 0xb5e0) - - lo=$((0x${x[15]} & 0x0F)) - hi=$((0x${x[15]} >> 4)) - zh=0x${gcm_ctx_hh[$lo]} - zl=0x${gcm_ctx_hl[$lo]} - - for (( i=15; i >=0; i=i-1 )); do - lo=$((0x${x[i]} & 0x0F)) - hi=$((0x${x[i]} >> 4)) - if [[ $i -ne 15 ]]; then - rem=$((zl & 0x0F)) - zl=$(((zl >> 4) & 0x0fffffffffffffff)) - zl=$(((zh << 60) | zl)) - zh=$(((zh >> 4) & 0x0fffffffffffffff)) - zh=$((zh^(last4[rem] << 48))) - zh=$((zh^0x${gcm_ctx_hh[$lo]})) - zl=$((zl^0x${gcm_ctx_hl[$lo]})) - fi - rem=$((zl & 0x0F)) - zl=$(((zl >> 4) & 0x0fffffffffffffff)) - zl=$(((zh << 60) | zl)) - zh=$(((zh >> 4) & 0x0fffffffffffffff)) - zh=$((zh^(last4[rem] << 48))) - zh=$((zh^0x${gcm_ctx_hh[$hi]})) - zl=$((zl^0x${gcm_ctx_hl[$hi]})) - done - output="$(printf "%016X" $zh)$(printf "%016X" $zl)" - tm_out "${output:0:2} ${output:2:2} ${output:4:2} ${output:6:2} ${output:8:2} ${output:10:2} ${output:12:2} ${output:14:2} ${output:16:2} ${output:18:2} ${output:20:2} ${output:22:2} ${output:24:2} ${output:26:2} ${output:28:2} ${output:30:2}" - return 0 -} - -# arg1: nonce (must be 96 bits) -# arg2: number of blocks needed for plaintext/ciphertext -# Generate the sequence of counter blocks, which are to be encrypted and then -# XORed with either the plaintext or the ciphertext. The first block that is -# encrypted is used in computing the authentication tag. -generate_gcm_ctr() { - local -i nr_blocks="$1" - local nonce="$2" - local -i i - local ctr="" - - for (( i=1; i <= nr_blocks; i++ )); do - ctr+="${nonce}$(printf "%08X" "$i")" - done - hex2binary "$ctr" - return 0 -} - -# arg1: an OpenSSL ecb cipher (e.g., -aes-128-ecb) -# arg2: key -# arg3: nonce (must be 96 bits in length) -# arg4: ciphertext -# arg5: aad -# arg6: mode -# arg7: true if authentication tag should be computed. false otherwise. -# This function is based on gcm_setkey, gcm_start, gcm_update, and gcm_finish -# in https://github.com/mko-x/SharedAES-GCM -gcm() { - local cipher="$1" aes_key="$2" nonce="$3" input="$4" aad="$5" mode="$6" - local compute_tag="$7" - local -a -i gcm_ctx_hl=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) - local -a -i gcm_ctx_hh=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) - local -a -i tag - local -a gcm_ctx_buf=("00" "00" "00" "00" "00" "00" "00" "00" "00" "00" "00" "00" "00" "00" "00" "00" ) - local -i i j hi lo vl vh t length - local h hl="" hh="" buf ectr base_ectr tmp - local -i input_len="$((${#input}/2))" aad_len="$((${#aad}/2))" use_len - - if "$compute_tag"; then - # gcm_setkey - populate HL and HH from gcm_ctx - h+=$(printf "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"| \ - $OPENSSL enc "$cipher" -K "$aes_key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"') - hi=0x${h:0:8} - lo=0x${h:8:8} - vh=$(((hi << 32) | lo)) - - hi=0x${h:16:8} - lo=0x${h:24:8} - vl=$(((hi << 32) | lo)) - - gcm_ctx_hl[8]=$vl - gcm_ctx_hh[8]=$vh - gcm_ctx_hh[0]=0 - gcm_ctx_hl[0]=0 - - for (( i=4; i > 0; i=i>>1 )); do - t=$(((vl & 1) * 0xe1000000)) - vl=$(((vl >> 1) & 0x7fffffffffffffff)) - vl=$(((vh << 63) | vl)) - vh=$(((vh >> 1) & 0x7fffffffffffffff)) - vh=$((vh ^ (t << 32))) - gcm_ctx_hl[i]=$vl - gcm_ctx_hh[i]=$vh - done - - for (( i=2; i < 16; i=i<<1 )); do - vh=${gcm_ctx_hh[i]} - vl=${gcm_ctx_hl[i]} - for (( j=1; j < i; j++ )); do - gcm_ctx_hh[$((i+j))]=$((vh ^ gcm_ctx_hh[j])) - gcm_ctx_hl[$((i+j))]=$((vl ^ gcm_ctx_hl[j])) - done - done - - # place HL and HH in strings so that can be passed to gcm_mult - for (( i=0; i < 16; i++ )); do - hl+="$(printf "%016X" ${gcm_ctx_hl[i]}) " - hh+="$(printf "%016X" ${gcm_ctx_hh[i]}) " - done - - # Feed any additional authenticated data into the computation for the authentication tag. - for (( i=0; i < aad_len; i+=use_len )); do - [[ $((aad_len-i)) -lt 16 ]] && use_len=$((aad_len-i)) || use_len=16 - for (( j=0; j < use_len; j++ )); do - gcm_ctx_buf[j]="$(printf "%02X" $((0x${gcm_ctx_buf[j]} ^ 0x${aad:$((2*i+2*j)):2})))" - done - - buf="$(gcm_mult $hl $hh ${gcm_ctx_buf[0]} ${gcm_ctx_buf[1]} ${gcm_ctx_buf[2]} ${gcm_ctx_buf[3]} ${gcm_ctx_buf[4]} ${gcm_ctx_buf[5]} ${gcm_ctx_buf[6]} ${gcm_ctx_buf[7]} ${gcm_ctx_buf[8]} ${gcm_ctx_buf[9]} ${gcm_ctx_buf[10]} ${gcm_ctx_buf[11]} ${gcm_ctx_buf[12]} ${gcm_ctx_buf[13]} ${gcm_ctx_buf[14]} ${gcm_ctx_buf[15]})" - read -r gcm_ctx_buf[0] gcm_ctx_buf[1] gcm_ctx_buf[2] gcm_ctx_buf[3] gcm_ctx_buf[4] gcm_ctx_buf[5] gcm_ctx_buf[6] gcm_ctx_buf[7] gcm_ctx_buf[8] gcm_ctx_buf[9] gcm_ctx_buf[10] gcm_ctx_buf[11] gcm_ctx_buf[12] gcm_ctx_buf[13] gcm_ctx_buf[14] gcm_ctx_buf[15] <<< "$buf" - done - fi - - j=$((1 + input_len/16)) - [[ $((input_len%16)) -ne 0 ]] && j+=1 - ectr="$(generate_gcm_ctr "$j" "$nonce" | $OPENSSL enc "$cipher" -K "$aes_key" -nopad 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - base_ectr="${ectr:0:32}" - ectr="${ectr:32}" - - # gcm_update - # Encrypt or decrypt the input and feed the ciphertext into the computation for the authentication tag. - for (( length=input_len; length > 0; length=length-use_len )); do - [[ $length -lt 16 ]] && use_len=$length || use_len=16 - - if [[ $use_len -eq 16 ]]; then - tmp="$(printf "%08X%08X%08X%08X" "$((0x${ectr:0:8} ^ 0x${input:0:8}))" "$((0x${ectr:8:8} ^ 0x${input:8:8}))" "$((0x${ectr:16:8} ^ 0x${input:16:8}))" "$((0x${ectr:24:8} ^ 0x${input:24:8}))")" - else - tmp="" - for (( i=0; i < use_len; i++ )); do - tmp+="$(printf "%02X" $((0x${ectr:$((2*i)):2} ^ 0x${input:$((2*i)):2})))" - done - fi - output+="$tmp" - if "$compute_tag"; then - [[ $mode == decrypt ]] && tmp="${input:0:32}" - for (( i=0; i < use_len; i++ )); do - gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x${tmp:$((2*i)):2})))" - done - fi - ectr="${ectr:32}" - - if "$compute_tag"; then - tmp="$(gcm_mult $hl $hh ${gcm_ctx_buf[0]} ${gcm_ctx_buf[1]} ${gcm_ctx_buf[2]} ${gcm_ctx_buf[3]} ${gcm_ctx_buf[4]} ${gcm_ctx_buf[5]} ${gcm_ctx_buf[6]} ${gcm_ctx_buf[7]} ${gcm_ctx_buf[8]} ${gcm_ctx_buf[9]} ${gcm_ctx_buf[10]} ${gcm_ctx_buf[11]} ${gcm_ctx_buf[12]} ${gcm_ctx_buf[13]} ${gcm_ctx_buf[14]} ${gcm_ctx_buf[15]})" - read -r gcm_ctx_buf[0] gcm_ctx_buf[1] gcm_ctx_buf[2] gcm_ctx_buf[3] gcm_ctx_buf[4] gcm_ctx_buf[5] gcm_ctx_buf[6] gcm_ctx_buf[7] gcm_ctx_buf[8] gcm_ctx_buf[9] gcm_ctx_buf[10] gcm_ctx_buf[11] gcm_ctx_buf[12] gcm_ctx_buf[13] gcm_ctx_buf[14] gcm_ctx_buf[15] <<< "$tmp" - fi - - input="${input:$((2*use_len))}" - done - - if "$compute_tag"; then - # gcm_finish - feed the lengths of the ciphertext and additional authenticated data - # into the computation for the authentication tag. - input_len=$((8*input_len)) - aad_len=$((8*aad_len)) - output+=" " - for (( i=0; i < 16; i++ )); do - tag[i]=0x${base_ectr:$((2*i)):2} - done - - if [[ $input_len -ne 0 ]] || [[ $aad_len -ne 0 ]]; then - buf="$(printf "%016X" $aad_len)$(printf "%016X" $input_len)" - for (( i=0; i < 16; i++ )); do - gcm_ctx_buf[i]="$(printf "%02X" $((0x${gcm_ctx_buf[i]} ^ 0x${buf:$((2*i)):2})))" - done - - buf="$(gcm_mult $hl $hh ${gcm_ctx_buf[0]} ${gcm_ctx_buf[1]} ${gcm_ctx_buf[2]} ${gcm_ctx_buf[3]} ${gcm_ctx_buf[4]} ${gcm_ctx_buf[5]} ${gcm_ctx_buf[6]} ${gcm_ctx_buf[7]} ${gcm_ctx_buf[8]} ${gcm_ctx_buf[9]} ${gcm_ctx_buf[10]} ${gcm_ctx_buf[11]} ${gcm_ctx_buf[12]} ${gcm_ctx_buf[13]} ${gcm_ctx_buf[14]} ${gcm_ctx_buf[15]})" - read -r gcm_ctx_buf[0] gcm_ctx_buf[1] gcm_ctx_buf[2] gcm_ctx_buf[3] gcm_ctx_buf[4] gcm_ctx_buf[5] gcm_ctx_buf[6] gcm_ctx_buf[7] gcm_ctx_buf[8] gcm_ctx_buf[9] gcm_ctx_buf[10] gcm_ctx_buf[11] gcm_ctx_buf[12] gcm_ctx_buf[13] gcm_ctx_buf[14] gcm_ctx_buf[15] <<< "$buf" - for (( i=0; i < 16; i++ )); do - tag[i]=$((tag[i] ^ 0x${gcm_ctx_buf[i]})) - done - fi - for (( i=0; i < 16; i++ )); do - output+="$(printf "%02X" ${tag[i]})" - done - fi - tm_out "$output" - return 0 -} - -# arg1: AES-GCM TLS cipher -# arg2: key -# arg3: nonce (must be 96 bits in length) -# arg4: ciphertext -# arg5: aad -# arg6: expected tag -# arg7: true if authentication tag should be checked. false otherwise. -gcm-decrypt() { - local cipher="$1" key="$2" nonce="$3" ciphertext="$4" aad="$5" expected_tag="$(toupper "$6")" - local compute_tag="$7" - local plaintext computed_tag tmp - - [[ ${#nonce} -ne 24 ]] && return 7 - - if [[ "$cipher" == TLS_AES_128_GCM_SHA256 ]] && "$HAS_AES128_GCM" && ! "$compute_tag"; then - plaintext="$(hex2binary "$ciphertext" | \ - $OPENSSL enc -aes-128-gcm -K "$key" -iv "$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - tm_out "$(strip_spaces "$plaintext")" - return 0 - elif [[ "$cipher" == TLS_AES_256_GCM_SHA384 ]] && "$HAS_AES256_GCM" && ! "$compute_tag"; then - plaintext="$(hex2binary "$ciphertext" | \ - $OPENSSL enc -aes-256-gcm -K "$key" -iv "$nonce" 2>/dev/null | hexdump -v -e '16/1 "%02X"')" - tm_out "$(strip_spaces "$plaintext")" - return 0 - fi - - case "$cipher" in - *AES_128*) cipher="-aes-128-ecb" ;; - *AES_256*) cipher="-aes-256-ecb" ;; - *) return 7 - esac - - tmp="$(gcm "$cipher" "$key" "$nonce" "$ciphertext" "$aad" "decrypt" "$compute_tag")" - [[ $? -ne 0 ]] && return 7 - computed_tag="${tmp##* }" - plaintext="${tmp% $computed_tag}" - - if ! "$compute_tag" || [[ "$computed_tag" == $expected_tag ]]; then - tm_out "$plaintext" - return 0 - else - return 7 - fi -} - -# arg1: AES-GCM TLS cipher -# arg2: key -# arg3: nonce (must be 96 bits in length) -# arg4: plaintext -# arg5: aad -# See Section 7.2 of SP 800-38D -gcm-encrypt() { - local cipher - - case "$1" in - *AES_128*) cipher="-aes-128-ecb" ;; - *AES_256*) cipher="-aes-256-ecb" ;; - *) return 7 - esac - [[ ${#3} -ne 24 ]] && return 7 - - tm_out "$(gcm "$cipher" "$2" "$3" "$4" "$5" "encrypt" true)" - return $? -} - -# arg1: TLS cipher -# arg2: key -# arg3: nonce (must be 96 bits in length) -# arg4: ciphertext -# arg5: additional authenticated data -sym-decrypt() { - local cipher="$1" - local key="$2" nonce="$3" - local ciphertext="$4" - local additional_data="$5" - local plaintext - local -i ciphertext_len tag_len - local compute_tag=false - - case "$cipher" in - *CCM_8*) - tag_len=16 ;; - *CCM*|*GCM*|*CHACHA20_POLY1305*) - tag_len=32 ;; - *) - return 7 ;; - esac - - # The final $tag_len characters of the ciphertext are the authentication tag - ciphertext_len=${#ciphertext} - [[ $ciphertext_len -lt $tag_len ]] && return 7 - ciphertext_len=$((ciphertext_len-tag_len)) - - # In general there is no need to verify that the authentication tag is correct - # when decrypting, and performing the check is time consuming when the - # computations are performed in Bash. If the ciphertext is very long (e.g., - # some application data), then trying to compute the authentication tag is - # too time consuming even for debug mode. - [[ $DEBUG -ge 1 ]] && [[ $ciphertext_len -le 1024 ]] && compute_tag=true - - if [[ "$cipher" =~ CHACHA20_POLY1305 ]]; then - plaintext="$(chacha20_aead_decrypt "$key" "$nonce" "${ciphertext:0:ciphertext_len}" "$additional_data" "${ciphertext:ciphertext_len:tag_len}" "$compute_tag")" - elif [[ "$cipher" =~ CCM ]]; then - plaintext=$(ccm-decrypt "$cipher" "$key" "$nonce" "${ciphertext:0:ciphertext_len}" "$additional_data" "${ciphertext:ciphertext_len:tag_len}" "$compute_tag") - else # GCM - plaintext=$(gcm-decrypt "$cipher" "$key" "$nonce" "${ciphertext:0:ciphertext_len}" "$additional_data" "${ciphertext:ciphertext_len:tag_len}" "$compute_tag") - fi - [[ $? -ne 0 ]] && return 7 - - tm_out "$plaintext" - return 0 -} - -# arg1: TLS cipher -# arg2: key -# arg3: nonce (must be 96 bits in length) -# arg4: plaintext -# arg5: additional authenticated data -sym-encrypt() { - local cipher="$1" key="$2" nonce="$3" plaintext="$4" additional_data="$5" - local ciphertext="" - - - if [[ "$cipher" =~ CCM ]]; then - ciphertext=$(ccm-encrypt "$cipher" "$key" "$nonce" "$plaintext" "$additional_data") - elif [[ "$cipher" =~ GCM ]]; then - ciphertext=$(gcm-encrypt "$cipher" "$key" "$nonce" "$plaintext" "$additional_data") - elif [[ "$cipher" =~ CHACHA20_POLY1305 ]]; then - ciphertext="$(chacha20_aead_encrypt "$key" "$nonce" "$plaintext" "$additional_data")" - else - return 7 - fi - [[ $? -ne 0 ]] && return 7 - - tm_out "$(strip_spaces "$ciphertext")" - return 0 -} - -# arg1: iv -# arg2: sequence number -get-nonce() { - local iv="$1" - local -i seq_num="$2" - local -i len lsb - local msb nonce - - len=${#iv} - [[ $len -lt 8 ]] && return 7 - i=$len-8 - msb="${iv:0:i}" - lsb="0x${iv:i:8}" - nonce="${msb}$(printf "%08X" "$((lsb ^ seq_num))")" - tm_out "$nonce" - return 0 -} - -# Return: -# 0 if arg1 contains the entire server response. -# 1 if arg1 does not contain the entire server response. -# 2 if the response is malformed. -# 3 if (a) the response version is TLSv1.3; -# (b) arg1 contains the entire ServerHello (and appears to contain the entire response); -# (c) the entire response is supposed to be parsed; and -# (d) the key and IV have not been provided to decrypt the response. -# arg1: ASCII-HEX encoded reply -# arg2: whether to process the full request ("all") or just the basic request plus the ephemeral key if any ("ephemeralkey"). -# arg3: TLS cipher for decrypting TLSv1.3 response -# arg4: handshake secret -# arg5: message transcript (up through ServerHello) -check_tls_serverhellodone() { - local tls_hello_ascii="$1" - local process_full="$2" - local cipher="$3" - local handshake_secret="$4" - local msg_transcript="$5" - local tls_handshake_ascii="" tls_alert_ascii="" - local -i i tls_hello_ascii_len tls_handshake_ascii_len tls_alert_ascii_len - local -i msg_len remaining tls_serverhello_ascii_len sid_len - local -i j offset tls_extensions_len extension_len - local tls_content_type tls_protocol tls_msg_type extension_type - local tls_err_level - local hash_fn handshake_traffic_keys key="" iv="" finished_key="" - local post_finished_msg="" - local -i seq_num=0 plaintext_len - local plaintext decrypted_response="" additional_data - local include_headers=true - - DETECTED_TLS_VERSION="" - - if [[ -n "$handshake_secret" ]]; then - handshake_traffic_keys="$(derive-handshake-traffic-keys "$cipher" "$handshake_secret" "$msg_transcript" "server")" - read -r key iv finished_key <<< "$handshake_traffic_keys" - fi - - if [[ -z "$tls_hello_ascii" ]]; then - return 0 # no server hello received - fi - - tls_hello_ascii_len=${#tls_hello_ascii} - for (( i=0; i $TMPFILE - - [[ "$DEBUG" -ge 5 ]] && echo $tls_hello_ascii # one line without any blanks - - # Client messages, including handshake messages, are carried by the record layer. - # First, extract the handshake and alert messages. - # see https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_record - # byte 0: content type: 0x14=CCS, 0x15=TLS alert x16=Handshake, 0x17 Application, 0x18=HB - # byte 1+2: TLS version word, major is 03, minor 00=SSL3, 01=TLS1 02=TLS1.1 03=TLS 1.2 - # byte 3+4: fragment length - # bytes 5...: message fragment - tls_hello_ascii_len=${#tls_hello_ascii} - if [[ $DEBUG -ge 3 ]] && [[ $tls_hello_ascii_len -gt 0 ]]; then - echo "TLS message fragments:" - fi - for (( i=0; i/dev/null)" - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 4 - elif [[ "$tls_hello_ascii" =~ 6130303220 ]]; then - [[ $DEBUG -ge 2 ]] && printf "%s\n" "probably IMAP plaintext reply \"$(hex2ascii "${tls_hello_ascii:0:32}" 2>/dev/null)\"" - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 3 - fi - fi - if [[ $tls_content_type != 14 ]] && [[ $tls_content_type != 15 ]] && \ - [[ $tls_content_type != 16 ]] && [[ $tls_content_type != 17 ]]; then - debugme tmln_warning "Content type other than alert, handshake, change cipher spec, or application data detected." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - elif [[ "${tls_protocol:0:2}" != 03 ]]; then - debugme tmln_warning "Protocol record_version.major is not 03." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - DETECTED_TLS_VERSION=$tls_protocol - - if [[ $msg_len -gt $tls_hello_ascii_len-$i ]]; then - if [[ "$process_full" =~ all ]]; then - debugme tmln_warning "Malformed message." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 7 - else - # This could just be a result of the server's response being split - # across two or more packets. Just grab the part that is available. - msg_len=$tls_hello_ascii_len-$i - fi - fi - - case "$tls_content_type" in - 15) tls_alert_ascii="$tls_alert_ascii${tls_hello_ascii:i:msg_len}" ;; - 16) tls_handshake_ascii="$tls_handshake_ascii${tls_hello_ascii:i:msg_len}" ;; - esac - done - - # Now check the alert messages. - tls_alert_ascii_len=${#tls_alert_ascii} - if [[ "$process_full" =~ all ]] && [[ $tls_alert_ascii_len%4 -ne 0 ]]; then - debugme tmln_warning "Malformed message." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - - if [[ $tls_alert_ascii_len -gt 0 ]]; then - echo "CONNECTED(00000003)" > $TMPFILE - debugme echo "TLS alert messages:" - for (( i=0; i+3 < tls_alert_ascii_len; i+=4 )); do - tls_err_level=${tls_alert_ascii:i:2} # 1: warning, 2: fatal - j=$i+2 - tls_err_descr_no=${tls_alert_ascii:j:2} - if [[ $DEBUG -ge 1 ]]; then - debugme tm_out " tls_err_descr_no: 0x${tls_err_descr_no} / = $(hex2dec ${tls_err_descr_no})" - tls_alert_descrip="$(tls_alert "$tls_err_descr_no")" - if [[ $DEBUG -ge 2 ]]; then - tmln_out " ($tls_alert_descrip)" - tm_out " tls_err_level: ${tls_err_level}" - fi - case $tls_err_level in - 01) echo -n "warning " >> $TMPFILE - debugme tmln_out " (warning)" ;; - 02) echo -n "fatal " >> $TMPFILE - debugme tmln_out " (fatal)" ;; - esac - echo "alert $tls_alert_descrip" >> $TMPFILE - echo "===============================================================================" >> $TMPFILE - fi - - if [[ "$tls_err_level" != 01 ]] && [[ "$tls_err_level" != 02 ]]; then - debugme tmln_warning "Unexpected AlertLevel (0x$tls_err_level)." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - elif [[ "$tls_err_level" == 02 ]]; then - # Fatal alert - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - done - fi - - # Now extract just the server hello, certificate, certificate status, - # and server key exchange handshake messages. - tls_handshake_ascii_len=${#tls_handshake_ascii} - if [[ $DEBUG -ge 3 ]] && [[ $tls_handshake_ascii_len -gt 0 ]]; then - echo "TLS handshake messages:" - fi - for (( i=0; i/dev/null | hexdump -v -e '16/1 "%02X"')" - tls_certificate_ascii="${tls_certificate_ascii%%[!0-9A-F]*}" - if [[ ${#tls_certificate_ascii} -ne $tls_certificate_ascii_len ]]; then - debugme tmln_warning "Length of uncompressed certificates did not match specified length." - return 1 - fi - fi - fi - done - - if [[ $tls_serverhello_ascii_len -eq 0 ]]; then - debugme echo "server hello empty, TCP connection closed" - DETECTED_TLS_VERSION="closed TCP connection " - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 # no server hello received - elif [[ $tls_serverhello_ascii_len -lt 76 ]]; then - DETECTED_TLS_VERSION="reply malformed" - debugme echo "Malformed response" - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - elif [[ "${tls_handshake_ascii:0:2}" != 02 ]]; then - # the ServerHello MUST be the first handshake message - DETECTED_TLS_VERSION="reply contained no ServerHello" - debugme tmln_warning "The first handshake protocol message is not a ServerHello." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - if [[ $tls_alert_ascii_len -eq 0 ]]; then - if [[ $DEBUG -eq 0 ]]; then - echo "CONNECTED(00000003)" > $TMPFILE - else - echo "CONNECTED(00000003)" >> $TMPFILE - fi - fi - - # First parse the server hello handshake message - # byte 0+1: 03, TLS version word see byte 1+2 - # byte 2-5: TLS timestamp for OpenSSL <1.01f - # byte 6-33: random, 28 bytes - # byte 34: session id length - # byte 35+36+sid-len: cipher suite! - # byte 37+sid-len: compression method: 00: none, 01: deflate, 64: LZS - # byte 38+39+sid-len: extension length - tls_protocol2="${tls_serverhello_ascii:0:4}" - DETECTED_TLS_VERSION="$tls_protocol2" - [[ "${DETECTED_TLS_VERSION:0:2}" == 7F ]] && DETECTED_TLS_VERSION="0304" - if [[ "${DETECTED_TLS_VERSION:0:2}" != 03 ]]; then - debugme tmln_warning "server_version.major in ServerHello is not 03." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - - if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then - tls_hello_time="${tls_serverhello_ascii:4:8}" - [[ "$TLS_DIFFTIME_SET" || "$DEBUG" ]] && TLS_TIME=$(hex2dec "$tls_hello_time") - tls_sid_len_hex="${tls_serverhello_ascii:68:2}" - tls_sid_len=2*$(hex2dec "$tls_sid_len_hex") - offset=$((tls_sid_len+70)) - if [[ $tls_serverhello_ascii_len -lt 76+$tls_sid_len ]]; then - debugme echo "Malformed response" - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - else - offset=68 - fi - - tls_cipher_suite="${tls_serverhello_ascii:offset:4}" - - if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then - offset=$((tls_sid_len+74)) - tls_compression_method="${tls_serverhello_ascii:offset:2}" - extns_offset=$((tls_sid_len+76)) - else - extns_offset=72 - fi - - if [[ $tls_serverhello_ascii_len -gt $extns_offset ]] && \ - [[ "$process_full" =~ all || "$DETECTED_TLS_VERSION" == 0303 || \ - ( "$process_full" == ephemeralkey && "0x${DETECTED_TLS_VERSION:2:2}" -gt "0x03" ) ]]; then - if [[ $tls_serverhello_ascii_len -lt $extns_offset+4 ]]; then - debugme echo "Malformed response" - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - tls_extensions_len=$(hex2dec "${tls_serverhello_ascii:extns_offset:4}")*2 - if [[ $tls_extensions_len -ne $tls_serverhello_ascii_len-$extns_offset-4 ]]; then - debugme tmln_warning "Malformed message." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - for (( i=0; i> $TMPFILE - offset=$((extns_offset+12+i)) - len1=2*$(hex2dec "${tls_serverhello_ascii:offset:4}") - if [[ $extension_len -lt $len1+4 ]] || [[ $len1 -lt 4 ]]; then - debugme tmln_warning "Malformed supported groups extension." - return 1 - fi - offset=$((offset+4)) - for (( j=0; j < len1; j+=4 )); do - [[ $j -ne 0 ]] && echo -n ", " >> $TMPFILE - case "${tls_serverhello_ascii:offset:4}" in - "0017") echo -n "secp256r1" >> $TMPFILE ;; - "0018") echo -n "secp384r1" >> $TMPFILE ;; - "0019") echo -n "secp521r1" >> $TMPFILE ;; - "001D") echo -n "X25519" >> $TMPFILE ;; - "001E") echo -n "X448" >> $TMPFILE ;; - "0100") echo -n "ffdhe2048" >> $TMPFILE ;; - "0101") echo -n "ffdhe3072" >> $TMPFILE ;; - "0102") echo -n "ffdhe4096" >> $TMPFILE ;; - "0103") echo -n "ffdhe6144" >> $TMPFILE ;; - "0104") echo -n "ffdhe8192" >> $TMPFILE ;; - *) echo -n "unknown (${tls_serverhello_ascii:offset:4})" >> $TMPFILE ;; - esac - offset=$((offset+4)) - done - echo "" >> $TMPFILE - fi - ;; - 000B) tls_extensions+="TLS server extension \"EC point formats\" (id=11), len=$extension_len\n" ;; - 000C) tls_extensions+="TLS server extension \"SRP\" (id=12), len=$extension_len\n" ;; - 000D) tls_extensions+="TLS server extension \"signature algorithms\" (id=13), len=$extension_len\n" ;; - 000E) tls_extensions+="TLS server extension \"use SRTP\" (id=14), len=$extension_len\n" ;; - 000F) tls_extensions+="TLS server extension \"heartbeat\" (id=15), len=$extension_len\n" ;; - 0010) tls_extensions+="TLS server extension \"application layer protocol negotiation\" (id=16), len=$extension_len\n" - if [[ "$process_full" =~ all ]]; then - if [[ $extension_len -lt 4 ]]; then - debugme echo "Malformed application layer protocol negotiation extension." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - echo -n "ALPN protocol: " >> $TMPFILE - offset=$((extns_offset+12+i)) - j=2*$(hex2dec "${tls_serverhello_ascii:offset:4}") - if [[ $extension_len -ne $j+4 ]] || [[ $j -lt 2 ]]; then - debugme echo "Malformed application layer protocol negotiation extension." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - offset=$((offset+4)) - j=2*$(hex2dec "${tls_serverhello_ascii:offset:2}") - if [[ $extension_len -ne $j+6 ]]; then - debugme echo "Malformed application layer protocol negotiation extension." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - offset=$((offset+2)) - hex2binary "${tls_serverhello_ascii:offset:j}" >> "$TMPFILE" - echo "" >> $TMPFILE - echo "===============================================================================" >> $TMPFILE - fi - ;; - 0011) tls_extensions+="TLS server extension \"certificate status version 2\" (id=17), len=$extension_len\n" ;; - 0012) tls_extensions+="TLS server extension \"signed certificate timestamps\" (id=18), len=$extension_len\n" ;; - 0013) tls_extensions+="TLS server extension \"client certificate type\" (id=19), len=$extension_len\n" ;; - 0014) tls_extensions+="TLS server extension \"server certificate type\" (id=20), len=$extension_len\n" ;; - 0015) tls_extensions+="TLS server extension \"TLS padding\" (id=21), len=$extension_len\n" ;; - 0016) tls_extensions+="TLS server extension \"encrypt-then-mac\" (id=22), len=$extension_len\n" ;; - 0017) tls_extensions+="TLS server extension \"extended master secret\" (id=23), len=$extension_len\n" ;; - 0018) tls_extensions+="TLS server extension \"token binding\" (id=24), len=$extension_len\n" ;; - 0019) tls_extensions+="TLS server extension \"cached info\" (id=25), len=$extension_len\n" ;; - 0023) tls_extensions+="TLS server extension \"session ticket\" (id=35), len=$extension_len\n" ;; - 0028|0033) - # The key share extension was renumbered from 40 to 51 in TLSv1.3 draft 23 since a few - # implementations have been using 40 for the extended_random extension. Since the - # server's version may not yet have been determined, assume that both values represent the - # key share extension. - if [[ "$extension_type" == "00$KEY_SHARE_EXTN_NR" ]]; then - tls_extensions+="TLS server extension \"key share\"" - else - tls_extensions+="TLS server extension \"unrecognized extension\"" - fi - if [[ "$extension_type" == 0028 ]]; then - tls_extensions+=" (id=40), len=$extension_len\n" - else - tls_extensions+=" (id=51), len=$extension_len\n" - fi - if [[ "$process_full" =~ all ]] || [[ "$process_full" == ephemeralkey ]]; then - if [[ $extension_len -lt 4 ]]; then - debugme tmln_warning "Malformed key share extension." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - offset=$((extns_offset+12+i)) - named_curve=$(hex2dec "${tls_serverhello_ascii:offset:4}") - offset=$((extns_offset+16+i)) - msg_len=2*"$(hex2dec "${tls_serverhello_ascii:offset:4}")" - if [[ $msg_len -ne $extension_len-8 ]]; then - debugme tmln_warning "Malformed key share extension." - [[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - case $named_curve in - 21) dh_bits=224 ; named_curve_str="P-224" ; named_curve_oid="06052b81040021" ;; - 23) dh_bits=256 ; named_curve_str="P-256" ; named_curve_oid="06082a8648ce3d030107" ;; - 24) dh_bits=384 ; named_curve_str="P-384" ; named_curve_oid="06052b81040022" ;; - 25) dh_bits=521 ; named_curve_str="P-521" ; named_curve_oid="06052b81040023" ;; - 29) dh_bits=253 ; named_curve_str="X25519" ;; - 30) dh_bits=448 ; named_curve_str="X448" ;; - 31) dh_bits=256 ; named_curve_str="brainpoolP256r1tls13" ; named_curve_oid="06092B2403030208010107" ;; - 32) dh_bits=384 ; named_curve_str="brainpoolP384r1tls13" ; named_curve_oid="06092B240303020801010B" ;; - 33) dh_bits=512 ; named_curve_str="brainpoolP512r1tls13" ; named_curve_oid="06092B240303020801010D" ;; - 256) dh_bits=2048 ; named_curve_str="ffdhe2048" ;; - 257) dh_bits=3072 ; named_curve_str="ffdhe3072" ;; - 258) dh_bits=4096 ; named_curve_str="ffdhe4096" ;; - 259) dh_bits=6144 ; named_curve_str="ffdhe6144" ;; - 260) dh_bits=8192 ; named_curve_str="ffdhe8192" ;; - *) named_curve_str="" ; named_curve_oid="" ;; - esac - offset=$((extns_offset+20+i)) - if ! "$HAS_PKEY"; then - # The key can't be extracted without the pkey utility. - key_bitstring="" - elif [[ $named_curve -eq 29 ]]; then - key_bitstring="302a300506032b656e032100${tls_serverhello_ascii:offset:msg_len}" - elif [[ $named_curve -eq 30 ]]; then - key_bitstring="3042300506032b656f033900${tls_serverhello_ascii:offset:msg_len}" - elif [[ $named_curve -lt 256 ]] && [[ -n "$named_curve_oid" ]]; then - len1="$(printf "%02x" $((msg_len/2+1)))" - [[ "0x${len1}" -ge "0x80" ]] && len1="81${len1}" - key_bitstring="03${len1}00${tls_serverhello_ascii:offset:msg_len}" - len2="$(printf "%02x" $((${#named_curve_oid}/2+9)))" - len3="$(printf "%02x" $((${#named_curve_oid}/2+${#key_bitstring}/2+11)))" - [[ "0x${len3}" -ge "0x80" ]] && len3="81${len3}" - key_bitstring="30${len3}30${len2}06072a8648ce3d0201${named_curve_oid}${key_bitstring}" - elif [[ "$named_curve_str" =~ "ffdhe" ]] && [[ "${TLS13_KEY_SHARES[named_curve]}" =~ "BEGIN" ]]; then - dh_param="$($OPENSSL pkey -pubout -outform DER 2>>$ERRFILE <<< "${TLS13_KEY_SHARES[named_curve]}" | hexdump -v -e '16/1 "%02X"')" - - # First is the length of the public-key SEQUENCE, and it is always encoded in four bytes (3082xxxx) - # Next is the length of the parameters SEQUENCE, and it is also always encoded in four bytes (3082xxxx) - dh_param_len=8+2*"$(hex2dec "${dh_param:12:4}")" - dh_param="${dh_param:8:dh_param_len}" - if [[ "0x${tls_serverhello_ascii:offset:2}" -ge 0x80 ]]; then - key_bitstring="00${tls_serverhello_ascii:offset:msg_len}" - msg_len+=2 - else - key_bitstring="${tls_serverhello_ascii:offset:msg_len}" - fi - len1="$(printf "%04x" $((msg_len/2)))" - key_bitstring="0282${len1}$key_bitstring" - len1="$(printf "%04x" $((${#key_bitstring}/2+1)))" - key_bitstring="${dh_param}0382${len1}00$key_bitstring" - len1="$(printf "%04x" $((${#key_bitstring}/2)))" - key_bitstring="3082${len1}$key_bitstring" - fi - if [[ -n "$key_bitstring" ]]; then - key_bitstring="$(hex2binary "$key_bitstring" | $OPENSSL pkey -pubin -inform DER 2>$ERRFILE)" - if [[ -z "$key_bitstring" ]] && [[ $DEBUG -ge 2 ]]; then - if [[ -n "$named_curve_str" ]]; then - prln_warning "Your $OPENSSL doesn't support $named_curve_str" - else - prln_warning "Your $OPENSSL doesn't support named curve $named_curve" - fi - fi - fi - fi - ;; - 0029) tls_extensions+="TLS server extension \"pre-shared key\" (id=41), len=$extension_len\n" ;; - 002A) tls_extensions+="TLS server extension \"early data\" (id=42), len=$extension_len\n" ;; - 002B) tls_extensions+="TLS server extension \"supported versions\" (id=43), len=$extension_len\n" - if [[ $extension_len -ne 4 ]]; then - debugme tmln_warning "Malformed supported versions extension." - return 1 - fi - offset=$((extns_offset+12+i)) - tls_protocol2="${tls_serverhello_ascii:offset:4}" - DETECTED_TLS_VERSION="$tls_protocol2" - [[ "${DETECTED_TLS_VERSION:0:2}" == 7F ]] && DETECTED_TLS_VERSION="0304" - ;; - 002C) tls_extensions+="TLS server extension \"cookie\" (id=44), len=$extension_len\n" ;; - 002D) tls_extensions+="TLS server extension \"psk key exchange modes\" (id=45), len=$extension_len\n" ;; - 002E) tls_extensions+="TLS server extension \"ticket early data info\" (id=46), len=$extension_len\n" ;; - 002F) tls_extensions+="TLS server extension \"certificate authorities\" (id=47), len=$extension_len\n" ;; - 0030) tls_extensions+="TLS server extension \"oid filters\" (id=48), len=$extension_len\n" ;; - 0031) tls_extensions+="TLS server extension \"post handshake auth\" (id=49), len=$extension_len\n" ;; - 3374) tls_extensions+="TLS server extension \"next protocol\" (id=13172), len=$extension_len\n" - if [[ "$process_full" =~ all ]]; then - local -i protocol_len - echo -n "Protocols advertised by server: " >> $TMPFILE - offset=$((extns_offset+12+i)) - for (( j=0; j> "$TMPFILE" - offset=$((offset+protocol_len)) - [[ $j+$protocol_len+2 -lt $extension_len ]] && echo -n ", " >> $TMPFILE - done - echo "" >> $TMPFILE - echo "===============================================================================" >> $TMPFILE - fi - ;; - FF01) tls_extensions+="TLS server extension \"renegotiation info\" (id=65281), len=$extension_len\n" ;; - *) tls_extensions+="TLS server extension \"unrecognized extension\" (id=$(printf "%d\n\n" "0x$extension_type")), len=$extension_len\n" ;; - esac - # After processing all of the extensions in the ServerHello message, - # if it has been determined that the response is TLSv1.3 and the - # response was decrypted, then modify $tls_serverhello_ascii by adding - # the extensions from the EncryptedExtensions and Certificate messages - # and then process them. - if ! "$added_encrypted_extensions" && [[ "$DETECTED_TLS_VERSION" == "0304" ]] && \ - [[ $((i+8+extension_len)) -eq $tls_extensions_len ]]; then - # Note that the encrypted extensions have been added so that - # the aren't added a second time. - added_encrypted_extensions=true - if [[ -n "$tls_encryptedextensions_ascii" ]]; then - tls_serverhello_ascii_len+=$tls_encryptedextensions_ascii_len-4 - tls_extensions_len+=$tls_encryptedextensions_ascii_len-4 - tls_encryptedextensions_ascii_len=$tls_encryptedextensions_ascii_len/2-2 - offset=$((extns_offset+4)) - tls_serverhello_ascii="${tls_serverhello_ascii:0:extns_offset}$(printf "%04X" $((0x${tls_serverhello_ascii:extns_offset:4}+tls_encryptedextensions_ascii_len)))${tls_serverhello_ascii:offset}${tls_encryptedextensions_ascii:4}" - fi - if [[ -n "$tls_certificate_ascii" ]]; then - # In TLS 1.3, the Certificate message begins with a zero length certificate_request_context. - # In addition, certificate_list is now a list of (certificate, extension) pairs rather than - # just certificates. So, extract the extensions and add them to $tls_serverhello_ascii and - # create a new $tls_certificate_ascii that only contains a list of certificates. - if [[ -n "$tls_certificate_ascii" ]]; then - if [[ "${tls_certificate_ascii:0:2}" != "00" ]]; then - debugme tmln_warning "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - if [[ $tls_certificate_ascii_len -lt 8 ]]; then - debugme tmln_warning "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - certificate_list_len=2*$(hex2dec "${tls_certificate_ascii:2:6}") - if [[ $certificate_list_len -ne $tls_certificate_ascii_len-8 ]]; then - debugme tmln_warning "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - for (( j=8; j < tls_certificate_ascii_len; j+=extn_len )); do - if [[ $tls_certificate_ascii_len-$j -lt 6 ]]; then - debugme tmln_warning "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - certificate_len=2*$(hex2dec "${tls_certificate_ascii:j:6}") - if [[ $certificate_len -gt $tls_certificate_ascii_len-$j-6 ]]; then - debugme tmln_warning "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - len1=$certificate_len+6 - tls_revised_certificate_msg+="${tls_certificate_ascii:j:len1}" - j+=$len1 - extn_len=2*$(hex2dec "${tls_certificate_ascii:j:4}") - j+=4 - # TODO: Should only the extensions associated with the EE certificate be added to $tls_serverhello_ascii? - tls_serverhello_ascii_len+=$extn_len - tls_extensions_len+=$extn_len - offset=$((extns_offset+4)) - tls_serverhello_ascii="${tls_serverhello_ascii:0:extns_offset}$(printf "%04X" $(( 0x${tls_serverhello_ascii:extns_offset:4}+extn_len/2)) )${tls_serverhello_ascii:offset}${tls_certificate_ascii:j:extn_len}" - done - tls_certificate_ascii_len=${#tls_revised_certificate_msg}+6 - tls_certificate_ascii="$(printf "%06X" $(( tls_certificate_ascii_len/2-3)) )$tls_revised_certificate_msg" - fi - fi - fi - done - fi - [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]] && [[ $tls_sid_len -gt 0 ]] && NO_SSL_SESSIONID=false - - if [[ "$DETECTED_TLS_VERSION" == "0300" ]]; then - echo "Protocol : SSLv3" >> $TMPFILE - else - echo "Protocol : TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" >> $TMPFILE - fi - echo "===============================================================================" >> $TMPFILE - if [[ $TLS_NR_CIPHERS -ne 0 ]]; then - if [[ "${tls_cipher_suite:0:2}" == "00" ]]; then - rfc_cipher_suite="$(show_rfc_style "x${tls_cipher_suite:2:2}")" - else - rfc_cipher_suite="$(show_rfc_style "x${tls_cipher_suite:0:4}")" - fi - elif "$HAS_CIPHERSUITES"; then - rfc_cipher_suite="$($OPENSSL ciphers -V -ciphersuites "$TLS13_OSSL_CIPHERS" 'ALL:COMPLEMENTOFALL' | grep -i " 0x${tls_cipher_suite:0:2},0x${tls_cipher_suite:2:2} " | awk '{ print $3 }')" - else - rfc_cipher_suite="$($OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL' | grep -i " 0x${tls_cipher_suite:0:2},0x${tls_cipher_suite:2:2} " | awk '{ print $3 }')" - fi - echo "Cipher : $rfc_cipher_suite" >> $TMPFILE - if [[ $dh_bits -ne 0 ]]; then - if [[ "$named_curve_str" =~ "ffdhe" ]]; then - echo "Server Temp Key: DH, $named_curve_str, $dh_bits bits" >> $TMPFILE - elif [[ "$named_curve_str" == "X25519" ]] || [[ "$named_curve_str" == "X448" ]]; then - echo "Server Temp Key: $named_curve_str, $dh_bits bits" >> $TMPFILE - else - echo "Server Temp Key: ECDH, $named_curve_str, $dh_bits bits" >> $TMPFILE - fi - fi - if [[ -n "$key_bitstring" ]]; then - echo "$key_bitstring" >> $TMPFILE - [[ "${TLS13_KEY_SHARES[named_curve]}" =~ "BEGIN" ]] && \ - echo "${TLS13_KEY_SHARES[named_curve]}" >> $TMPFILE - fi - echo "===============================================================================" >> $TMPFILE - if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then - case $tls_compression_method in - 00) echo "Compression: NONE" >> $TMPFILE ;; - 01) echo "Compression: zlib compression" >> $TMPFILE ;; - 40) echo "Compression: LZS compression" >> $TMPFILE ;; - *) echo "Compression: unrecognized compression method" >> $TMPFILE ;; - esac - echo "===============================================================================" >> $TMPFILE - fi - if [[ -n "$cert_compression_method" ]]; then - echo "Certificate Compression Algorithm: $cert_compression_method ($cert_compression_method_str)" >> $TMPFILE - fi - [[ -n "$tls_extensions" ]] && echo -e "$tls_extensions" >> $TMPFILE - - if [[ $DEBUG -ge 3 ]]; then - echo "TLS server hello message:" - if [[ $DEBUG -ge 4 ]]; then - echo " tls_protocol: 0x$tls_protocol2" - [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]] && echo " tls_sid_len: 0x$tls_sid_len_hex / = $((tls_sid_len/2))" - fi - if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then - echo -n " tls_hello_time: 0x$tls_hello_time " - parse_date "$TLS_TIME" "+%Y-%m-%d %r" "%s" # in debugging mode we don't mind the cycles and don't use TLS_DIFFTIME_SET - fi - echo -n " tls_cipher_suite: 0x$tls_cipher_suite" - if [[ -n "$rfc_cipher_suite" ]]; then - echo " ($rfc_cipher_suite)" - else - echo "" - fi - if [[ $dh_bits -ne 0 ]]; then - if [[ "$named_curve_str" =~ "ffdhe" ]]; then - echo " dh_bits: DH, $named_curve_str, $dh_bits bits" - elif [[ "$named_curve_str" == "X25519" ]] || [[ "$named_curve_str" == "X448" ]]; then - echo " dh_bits: $named_curve_str, $dh_bits bits" - else - echo " dh_bits: ECDH, $named_curve_str, $dh_bits bits" - fi - fi - if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then - echo -n " tls_compression_method: 0x$tls_compression_method " - case $tls_compression_method in - 00) echo "(NONE)" ;; - 01) echo "(zlib compression)" ;; - 40) echo "(LZS compression)" ;; - *) echo "(unrecognized compression method)" ;; - esac - fi - if [[ -n "$tls_extensions" ]]; then - echo -n " tls_extensions: " - newline_to_spaces "$(grep -a 'TLS server extension ' $TMPFILE | \ - sed -e 's/TLS server extension //g' -e 's/\" (id=/\/#/g' \ - -e 's/,.*$/,/g' -e 's/),$/\"/g' \ - -e 's/elliptic curves\/#10/supported_groups\/#10/g')" - echo "" - if [[ "$tls_extensions" =~ supported_groups ]]; then - echo " Supported Groups: $(grep "Supported groups:" "$TMPFILE" | sed 's/Supported groups: //')" - fi - if [[ "$tls_extensions" =~ application\ layer\ protocol\ negotiation ]]; then - echo " ALPN protocol: $(grep "ALPN protocol:" "$TMPFILE" | sed 's/ALPN protocol: //')" - fi - if [[ "$tls_extensions" =~ next\ protocol ]]; then - echo " NPN protocols: $(grep "Protocols advertised by server:" "$TMPFILE" | sed 's/Protocols advertised by server: //')" - fi - fi - tmln_out - fi - - # If a CIPHER_SUITES string was provided, then check that $tls_cipher_suite is in the string. - # this appeared in yassl + MySQL (https://github.com/drwetter/testssl.sh/pull/784) but adds robustness - # to the implementation - if [[ -n "$cipherlist" ]]; then - tls_cipher_suite="$(tolower "$tls_cipher_suite")" - tls_cipher_suite="${tls_cipher_suite:0:2}\\x${tls_cipher_suite:2:2}" - cipherlist_len=${#cipherlist} - for (( i=0; i < cipherlist_len; i+=8 )); do - # At the right hand side we need the quotes here! - [[ "${cipherlist:i:6}" == "$tls_cipher_suite" ]] && break - done - if [[ $i -ge $cipherlist_len ]]; then - BAD_SERVER_HELLO_CIPHER=true - debugme echo "The ServerHello specifies a cipher suite that wasn't included in the ClientHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - fi - - # If the ClientHello included a supported_versions extension, then check that the - # $DETECTED_TLS_VERSION appeared in the list offered in the ClientHello. - if [[ "${TLS_CLIENT_HELLO:0:2}" == 01 ]]; then - # get position of cipher lists (just after session id) - offset=78+2*$(hex2dec "${TLS_CLIENT_HELLO:76:2}") - # get position of compression methods - offset+=4+2*$(hex2dec "${TLS_CLIENT_HELLO:offset:4}") - # get position of extensions - extns_offset=$offset+6+2*$(hex2dec "${TLS_CLIENT_HELLO:offset:2}") - len1=${#TLS_CLIENT_HELLO} - for (( i=extns_offset; i < len1; i+=8+extension_len )); do - extension_type="${TLS_CLIENT_HELLO:i:4}" - offset=4+$i - extension_len=2*$(hex2dec "${TLS_CLIENT_HELLO:offset:4}") - if [[ "$extension_type" == 002b ]]; then - offset+=6 - tls_protocol2="$(tolower "$tls_protocol2")" - for (( j=0; j < extension_len-2; j+=4 )); do - [[ "${TLS_CLIENT_HELLO:offset:4}" == $tls_protocol2 ]] && break - offset+=4 - done - if [[ $j -eq $extension_len-2 ]]; then - debugme echo "The ServerHello specifies a version that wasn't offered in the ClientHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - break - fi - done - fi - - # Now parse the Certificate message. - if [[ "$process_full" =~ all ]]; then - # not sure why we need this - [[ -e "$HOSTCERT" ]] && rm "$HOSTCERT" - [[ -e "$TEMPDIR/intermediatecerts.pem" ]] && > "$TEMPDIR/intermediatecerts.pem" - fi - if [[ $tls_certificate_ascii_len -ne 0 ]]; then - # The first certificate is the server's certificate. If there are anything - # subsequent certificates, they are intermediate certificates. - if [[ $tls_certificate_ascii_len -lt 12 ]]; then - debugme echo "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - certificate_list_len=2*$(hex2dec "${tls_certificate_ascii:0:6}") - if [[ $certificate_list_len -ne $tls_certificate_ascii_len-6 ]]; then - debugme echo "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - - # Place server's certificate in $HOSTCERT - certificate_len=2*$(hex2dec "${tls_certificate_ascii:6:6}") - if [[ $certificate_len -gt $tls_certificate_ascii_len-12 ]]; then - debugme echo "Malformed Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - hex2binary "${tls_certificate_ascii:12:certificate_len}" | \ - $OPENSSL x509 -inform DER -outform PEM -out "$HOSTCERT" 2>$ERRFILE - if [[ $? -ne 0 ]]; then - debugme echo "Malformed certificate in Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - get_pub_key_size - echo "===============================================================================" >> $TMPFILE - echo "---" >> $TMPFILE - echo "Certificate chain" >> $TMPFILE - subjectDN="$($OPENSSL x509 -in $HOSTCERT -noout -subject 2>>$ERRFILE)" - issuerDN="$($OPENSSL x509 -in $HOSTCERT -noout -issuer 2>>$ERRFILE)" - echo " $nr_certs s:${subjectDN:9}" >> $TMPFILE - echo " i:${issuerDN:8}" >> $TMPFILE - cat "$HOSTCERT" >> $TMPFILE - - echo "" > "$TEMPDIR/intermediatecerts.pem" - # Place any additional certificates in $TEMPDIR/intermediatecerts.pem - CERTIFICATE_LIST_ORDERING_PROBLEM=false - CAissuerDN="$issuerDN" - for (( i=12+certificate_len; i$ERRFILE)" - if [[ $? -ne 0 ]]; then - debugme echo "Malformed certificate in Certificate Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - nr_certs+=1 - CAsubjectDN="$($OPENSSL x509 -noout -subject 2>>$ERRFILE <<< "$pem_certificate")" - # Check that this certificate certifies the one immediately preceding it. - [[ "${CAsubjectDN:9}" != "${CAissuerDN:8}" ]] && CERTIFICATE_LIST_ORDERING_PROBLEM=true - CAissuerDN="$($OPENSSL x509 -noout -issuer 2>>$ERRFILE <<< "$pem_certificate")" - echo " $nr_certs s:${CAsubjectDN:9}" >> $TMPFILE - echo " i:${CAissuerDN:8}" >> $TMPFILE - echo "$pem_certificate" >> $TMPFILE - echo "$pem_certificate" >> "$TEMPDIR/intermediatecerts.pem" - if [[ -z "$hostcert_issuer" ]] && [[ "${CAsubjectDN:9}" == "${issuerDN:8}" ]]; then - # The issuer's certificate is needed if there is a stapled OCSP response, - # and it may be needed if check_revocation_ocsp() will later be called - # with the OCSP URI in the server's certificate. - hostcert_issuer="$TEMPDIR/hostcert_issuer.pem" - echo "$pem_certificate" > "$hostcert_issuer" - fi - done - echo "---" >> $TMPFILE - echo "Server certificate" >> $TMPFILE - echo "subject=${subjectDN:9}" >> $TMPFILE - echo "issuer=${issuerDN:8}" >> $TMPFILE - echo "---" >> $TMPFILE - fi - - # Now parse the certificate status message - if [[ $tls_certificate_status_ascii_len -ne 0 ]] && [[ $tls_certificate_status_ascii_len -lt 8 ]]; then - debugme echo "Malformed certificate status Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - elif [[ $tls_certificate_status_ascii_len -ne 0 ]] && [[ "${tls_certificate_status_ascii:0:2}" == "01" ]]; then - # This is a certificate status message of type "ocsp" - ocsp_response_len=2*$(hex2dec "${tls_certificate_status_ascii:2:6}") - if [[ $ocsp_response_len -ne $tls_certificate_status_ascii_len-8 ]]; then - debugme echo "Malformed certificate status Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - ocsp_resp_offset=8 - elif [[ $tls_certificate_status_ascii_len -ne 0 ]] && [[ "${tls_certificate_status_ascii:0:2}" == "02" ]]; then - # This is a list of OCSP responses, but only the first one is needed - # since the first one corresponds to the server's certificate. - ocsp_response_list_len=2*$(hex2dec "${tls_certificate_status_ascii:2:6}") - if [[ $ocsp_response_list_len -ne $tls_certificate_status_ascii_len-8 ]] || [[ $ocsp_response_list_len -lt 6 ]]; then - debugme echo "Malformed certificate status Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - ocsp_response_len=2*$(hex2dec "${tls_certificate_status_ascii:8:6}") - if [[ $ocsp_response_len -gt $ocsp_response_list_len-6 ]]; then - debugme echo "Malformed certificate status Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - ocsp_resp_offset=14 - fi - STAPLED_OCSP_RESPONSE="" - if [[ $ocsp_response_len -ne 0 ]]; then - STAPLED_OCSP_RESPONSE="${tls_certificate_status_ascii:ocsp_resp_offset:ocsp_response_len}" - echo "OCSP response:" >> $TMPFILE - echo "===============================================================================" >> $TMPFILE - if [[ -n "$hostcert_issuer" ]]; then - hex2binary "$STAPLED_OCSP_RESPONSE" | \ - $OPENSSL ocsp -no_nonce -CAfile $TEMPDIR/intermediatecerts.pem -issuer $hostcert_issuer -cert $HOSTCERT -respin /dev/stdin -resp_text >> $TMPFILE 2>$ERRFILE - else - hex2binary "$STAPLED_OCSP_RESPONSE" | \ - $OPENSSL ocsp -respin /dev/stdin -resp_text >> $TMPFILE 2>$ERRFILE - fi - echo "===============================================================================" >> $TMPFILE - elif [[ "$process_full" =~ all ]]; then - echo "OCSP response: no response sent" >> $TMPFILE - echo "===============================================================================" >> $TMPFILE - fi - - # Now parse the server key exchange message - if [[ $tls_serverkeyexchange_ascii_len -ne 0 ]]; then - if [[ $rfc_cipher_suite =~ TLS_ECDHE_ ]] || [[ $rfc_cipher_suite =~ TLS_ECDH_anon ]] || \ - [[ $rfc_cipher_suite == ECDHE* ]] || [[ $rfc_cipher_suite == AECDH* ]]; then - if [[ $tls_serverkeyexchange_ascii_len -lt 6 ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - curve_type=$(hex2dec "${tls_serverkeyexchange_ascii:0:2}") - if [[ $curve_type -eq 3 ]]; then - # named_curve - the curve is identified by a 2-byte number - named_curve=$(hex2dec "${tls_serverkeyexchange_ascii:2:4}") - # https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 - case $named_curve in - 1) dh_bits=163 ; named_curve_str="K-163" ;; - 2) dh_bits=162 ; named_curve_str="sect163r1" ;; - 3) dh_bits=163 ; named_curve_str="B-163" ;; - 4) dh_bits=193 ; named_curve_str="sect193r1" ;; - 5) dh_bits=193 ; named_curve_str="sect193r2" ;; - 6) dh_bits=232 ; named_curve_str="K-233" ;; - 7) dh_bits=233 ; named_curve_str="B-233" ;; - 8) dh_bits=238 ; named_curve_str="sect239k1" ;; - 9) dh_bits=281 ; named_curve_str="K-283" ;; - 10) dh_bits=282 ; named_curve_str="B-283" ;; - 11) dh_bits=407 ; named_curve_str="K-409" ;; - 12) dh_bits=409 ; named_curve_str="B-409" ;; - 13) dh_bits=570 ; named_curve_str="K-571" ;; - 14) dh_bits=570 ; named_curve_str="B-571" ;; - 15) dh_bits=161 ; named_curve_str="secp160k1" ;; - 16) dh_bits=161 ; named_curve_str="secp160r1" ;; - 17) dh_bits=161 ; named_curve_str="secp160r2" ;; - 18) dh_bits=192 ; named_curve_str="secp192k1" ;; - 19) dh_bits=192 ; named_curve_str="P-192" ;; - 20) dh_bits=225 ; named_curve_str="secp224k1" ;; - 21) dh_bits=224 ; named_curve_str="P-224" ;; - 22) dh_bits=256 ; named_curve_str="secp256k1" ;; - 23) dh_bits=256 ; named_curve_str="P-256" ;; - 24) dh_bits=384 ; named_curve_str="P-384" ;; - 25) dh_bits=521 ; named_curve_str="P-521" ;; - 26) dh_bits=256 ; named_curve_str="brainpoolP256r1" ;; - 27) dh_bits=384 ; named_curve_str="brainpoolP384r1" ;; - 28) dh_bits=512 ; named_curve_str="brainpoolP512r1" ;; - 29) dh_bits=253 ; named_curve_str="X25519" ;; - 30) dh_bits=448 ; named_curve_str="X448" ;; - esac - if [[ "$DETECTED_TLS_VERSION" == 0303 ]]; then - # Skip over the public key to get to the SignatureAndHashAlgorithm - # This is TLS 1.2-only, as this field does not appear in earlier versions. - len1=2*$(hex2dec "${tls_serverkeyexchange_ascii:6:2}") - offset=$((len1+8)) - if [[ $tls_serverkeyexchange_ascii_len -ge $((offset+4)) ]]; then - # The SignatureAndHashAlgorithm won't be present in an anonymous - # key exchange. - peering_signing_digest="${tls_serverkeyexchange_ascii:offset:2}" - peer_signature_type="${tls_serverkeyexchange_ascii:$((offset+2)):2}" - fi - fi - fi - if [[ $dh_bits -ne 0 ]] && [[ $named_curve -ne 29 ]] && [[ $named_curve -ne 30 ]]; then - [[ $DEBUG -ge 3 ]] && echo -e " dh_bits: ECDH, $named_curve_str, $dh_bits bits" - echo "Server Temp Key: ECDH, $named_curve_str, $dh_bits bits" >> $TMPFILE - elif [[ $dh_bits -ne 0 ]]; then - [[ $DEBUG -ge 3 ]] && echo -e " dh_bits: $named_curve_str, $dh_bits bits" - echo "Server Temp Key: $named_curve_str, $dh_bits bits" >> $TMPFILE - fi - elif [[ $rfc_cipher_suite =~ TLS_DHE_ ]] || [[ $rfc_cipher_suite =~ TLS_DH_anon ]] || \ - [[ $rfc_cipher_suite == "DHE-"* ]] || [[ $rfc_cipher_suite == "EDH-"* ]] || \ - [[ $rfc_cipher_suite == "EXP1024-DHE-"* ]]; then - # For DH ephemeral keys the first field is p, and the length of - # p is the same as the length of the public key. - if [[ $tls_serverkeyexchange_ascii_len -lt 4 ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - dh_p_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:0:4}") - offset=4+$dh_p_len - if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - - # Subtract any leading 0 bytes - for (( i=4; i < offset; i+=2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_p_len=$dh_p_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - dh_p="${tls_serverkeyexchange_ascii:i:dh_p_len}" - - dh_bits=4*$dh_p_len - msb=$(hex2dec "${tls_serverkeyexchange_ascii:i:2}") - for (( mask=128; msb < mask; mask/=2 )); do - dh_bits=$dh_bits-1 - done - - key_bitstring="$(get_dh_ephemeralkey "$tls_serverkeyexchange_ascii")" - [[ $? -eq 0 ]] && echo "$key_bitstring" >> $TMPFILE - - # Check to see whether the ephemeral public key uses one of the groups from - # RFC 7919 for parameters - case $dh_bits in - 2048) named_curve=256; named_curve_str=" ffdhe2048," ;; - 3072) named_curve=257; named_curve_str=" ffdhe3072," ;; - 4096) named_curve=258; named_curve_str=" ffdhe4096," ;; - 6144) named_curve=259; named_curve_str=" ffdhe6144," ;; - 8192) named_curve=260; named_curve_str=" ffdhe8192," ;; - *) named_curve=0; named_curve_str="" ;; - esac - [[ -z "$key_bitstring" ]] && named_curve=0 && named_curve_str="" - if "$HAS_PKEY" && [[ $named_curve -ne 0 ]] && [[ "${TLS13_KEY_SHARES[named_curve]}" =~ BEGIN ]]; then - ephemeral_param="$($OPENSSL pkey -pubin -text_pub -noout 2>>$ERRFILE <<< "$key_bitstring")" - # OpenSSL 3.0.0 outputs the group name rather than the actual parameter values for some named groups. - if [[ "$ephemeral_param" =~ GROUP: ]]; then - ephemeral_param="${ephemeral_param#*GROUP: }" - rfc7919_param="${named_curve_str# }" - rfc7919_param="${rfc7919_param%,}" - [[ "$ephemeral_param" =~ $rfc7919_param ]] || named_curve_str="" - else - ephemeral_param="$(grep -EA 1000 "prime:|P:" <<< "$ephemeral_param")" - rfc7919_param="$($OPENSSL pkey -text_pub -noout 2>>$ERRFILE <<< "${TLS13_KEY_SHARES[named_curve]}" | grep -EA 1000 "prime:|P:")" - [[ "$ephemeral_param" != "$rfc7919_param" ]] && named_curve_str="" - fi - fi - - [[ $DEBUG -ge 3 ]] && [[ $dh_bits -ne 0 ]] && echo -e " dh_bits: DH,$named_curve_str $dh_bits bits" - [[ $dh_bits -ne 0 ]] && echo "Server Temp Key: DH,$named_curve_str $dh_bits bits" >> $TMPFILE - if [[ "$DETECTED_TLS_VERSION" == 0303 ]]; then - # Skip over the public key (P, G, Y) to get to the SignatureAndHashAlgorithm - # This is TLS 1.2-only, as this field does not appear in earlier versions. - offset=$((dh_p_len+4)) - if [[ $tls_serverkeyexchange_ascii_len -lt $((offset+4)) ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - len1=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - offset+=$((len1+4)) - if [[ $tls_serverkeyexchange_ascii_len -lt $((offset+4)) ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle ${FUNCNAME[0]}.txt - return 1 - fi - len1=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - offset+=$((len1+4)) - if [[ $tls_serverkeyexchange_ascii_len -ge $((offset+4)) ]]; then - # The SignatureAndHashAlgorithm won't be present in an anonymous - # key exchange. - peering_signing_digest="${tls_serverkeyexchange_ascii:offset:2}" - peer_signature_type="${tls_serverkeyexchange_ascii:$((offset+2)):2}" - fi - fi - fi - fi - if [[ 0x$peering_signing_digest -eq 8 ]] && \ - [[ 0x$peer_signature_type -ge 4 ]] && [[ 0x$peer_signature_type -le 11 ]]; then - case $peer_signature_type in - 04) peering_signing_digest="SHA256"; peer_signature_type="RSA-PSS-RSAE" ;; - 05) peering_signing_digest="SHA384"; peer_signature_type="RSA-PSS-RSAE" ;; - 06) peering_signing_digest="SHA512"; peer_signature_type="RSA-PSS-RSAE" ;; - 07) peering_signing_digest=""; peer_signature_type="Ed25519" ;; - 08) peering_signing_digest=""; peer_signature_type="Ed448" ;; - 09) peering_signing_digest="SHA256"; peer_signature_type="RSA-PSS-PSS" ;; - 0A) peering_signing_digest="SHA384"; peer_signature_type="RSA-PSS-PSS" ;; - 0B) peering_signing_digest="SHA512"; peer_signature_type="RSA-PSS-PSS" ;; - esac - if [[ -n "$peering_signing_digest" ]]; then - echo "Peer signing digest: $peering_signing_digest" >> $TMPFILE - [[ $DEBUG -ge 3 ]] && echo -e " Peer signing digest: $peering_signing_digest" - fi - echo "Peer signature type: $peer_signature_type" >> $TMPFILE - [[ $DEBUG -ge 3 ]] && echo -e " Peer signature type: $peer_signature_type\n" - elif [[ 0x$peering_signing_digest -ge 1 ]] && [[ 0x$peering_signing_digest -le 6 ]] && \ - [[ 0x$peer_signature_type -ge 1 ]] && [[ 0x$peer_signature_type -le 3 ]]; then - case $peering_signing_digest in - 01) peering_signing_digest="MD5" ;; - 02) peering_signing_digest="SHA1" ;; - 03) peering_signing_digest="SHA224" ;; - 04) peering_signing_digest="SHA256" ;; - 05) peering_signing_digest="SHA384" ;; - 06) peering_signing_digest="SHA512" ;; - esac - case $peer_signature_type in - 01) peer_signature_type="RSA" ;; - 02) peer_signature_type="DSA" ;; - 03) peer_signature_type="ECDSA" ;; - esac - echo "Peer signing digest: $peering_signing_digest" >> $TMPFILE - [[ $DEBUG -ge 3 ]] && echo -e " Peer signing digest: $peering_signing_digest" - echo "Peer signature type: $peer_signature_type" >> $TMPFILE - [[ $DEBUG -ge 3 ]] && echo -e " Peer signature type: $peer_signature_type\n" - fi - tmpfile_handle ${FUNCNAME[0]}.txt - - TLS_SERVER_HELLO="02$(printf "%06x" $(( tls_serverhello_ascii_len/2)) )${tls_serverhello_ascii}" - return 0 -} - -# ASCII-HEX encoded session ticket -parse_tls13_new_session_ticket() { - local tls_version="$1" - local new_session_ticket="$2" - local -i len ticket_lifetime ticket_age_add min_len remainder - local ticket_nonce ticket extensions - local has_nonce=true - - [[ "${new_session_ticket:0:2}" == 04 ]] || return 7 - # Prior to draft 21 the NewSessionTicket did not include a ticket_nonce. - [[ "${tls_version:0:2}" == 7F ]] && [[ 0x${tls_version:2:2} -le 20 ]] && has_nonce=false - - # Set min_len to the minimum length that a session ticket can be. - min_len=28 - "$has_nonce" || min_len=$((min_len-2)) - - remainder=$((2*0x${new_session_ticket:2:6})) - [[ $remainder -ge $min_len ]] || return 7 - [[ ${#new_session_ticket} -ge $((remainder + 8)) ]] || return 7 - - ticket_lifetime=0x${new_session_ticket:8:8} - ticket_age_add=0x${new_session_ticket:16:8} - new_session_ticket="${new_session_ticket:24}" - remainder=$((remainder-16)) - - if "$has_nonce"; then - len=$((2*0x${new_session_ticket:0:2})) - new_session_ticket="${new_session_ticket:2}" - [[ $remainder -ge $((len + 12)) ]] || return 7 - ticket_nonce="${new_session_ticket:0:len}" - new_session_ticket="${new_session_ticket:len}" - remainder=$((remainder-len-2)) - fi - - len=$((2*0x${new_session_ticket:0:4})) - new_session_ticket="${new_session_ticket:4}" - [[ $remainder -ge $((len + 8)) ]] || return 7 - ticket="${new_session_ticket:0:len}" - new_session_ticket="${new_session_ticket:len}" - remainder=$((remainder-len-4)) - - len=$((2*0x${new_session_ticket:0:4})) - new_session_ticket="${new_session_ticket:4}" - [[ $remainder -eq $((len + 4)) ]] || return 7 - extensions="${new_session_ticket:0:len}" - - echo " TLS session ticket lifetime hint: $ticket_lifetime (seconds)" > $TMPFILE - tmpfile_handle ${FUNCNAME[0]}.txt $TMPFILE - return 0 -} - -#arg1 (optional): list of ciphers suites or empty -#arg2 (optional): "true" if full server response should be parsed. -# return: 6: couldn't open socket, 3(!): sslv2 handshake succeeded, 0=no SSLv2 -# 1,4,6,7: see return value of parse_sslv2_serverhello() -sslv2_sockets() { - local ret - local cipher_suites="$1" - local client_hello len_client_hello - local len_ciph_suites - local server_hello sock_reply_file2 foo - local -i len_ciph_suites_byte response_len server_hello_len - local parse_complete=false - - # this could be empty so we use '==' - if [[ "$2" == true ]]; then - parse_complete=true - fi - if [[ -z "$cipher_suites" ]]; then - cipher_suites=" - 05,00,80, # 1st cipher 9 cipher specs, only classical V2 ciphers are used here, see FIXME below - 03,00,80, # 2nd there are v3 in v2!!! : https://tools.ietf.org/html/rfc6101#appendix-E - 01,00,80, # 3rd Cipher specifications introduced in version 3.0 can be included in version 2.0 client hello messages using - 07,00,c0, # 4th the syntax below. [..] # V2CipherSpec (see Version 3.0 name) = { 0x00, CipherSuite }; !!!! - 08,00,80, # 5th - 06,00,40, # 6th - 04,00,80, # 7th - 02,00,80, # 8th - 06,01,40, # 9 - 07,01,c0, # 10 - FF,80,00, # 11 - FF,80,10, # 12 - 00,00,00" # 13 - # FIXME: also SSLv3 ciphers, see - # https://web.archive.org/web/20170310142840/http://max.euston.net/d/tip_sslciphers.html - fi - - code2network "$cipher_suites" # convert CIPHER_SUITES - cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next - len_ciph_suites_byte=${#cipher_suites} - - len_ciph_suites_byte+=2 - len_ciph_suites=$(printf "%02x\n" $(( len_ciph_suites_byte / 4 ))) - len_client_hello=$(printf "%02x\n" $((0x$len_ciph_suites + 0x19))) - - client_hello=" - ,80,$len_client_hello # length - ,01 # Client Hello - ,00,02 # SSLv2 - ,00,$len_ciph_suites # cipher spec length - ,00,00 # session ID length - ,00,10 # challenge length - ,$cipher_suites - ,29,22,be,b3,5a,01,8b,04,fe,5f,80,03,a0,13,eb,c4" # Challenge - # https://idea.popcount.org/2012-06-16-dissecting-ssl-handshake/ (client) - - fd_socket 5 || return 6 - debugme echo -n "sending client hello... " - socksend_clienthello "$client_hello" - - sockread 32768 - if "$parse_complete"; then - if [[ -s "$SOCK_REPLY_FILE" ]]; then - server_hello=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") - server_hello_len=$((2 + $(hex2dec "${server_hello:1:3}") )) - foo="$(wc -c "$SOCK_REPLY_FILE")" - response_len="${foo% *}" - for (( 1; response_len < server_hello_len; 1 )); do - sock_reply_file2=${SOCK_REPLY_FILE}.2 - mv "$SOCK_REPLY_FILE" "$sock_reply_file2" - - debugme echo -n "requesting more server hello data... " - socksend "" $USLEEP_SND - sockread 32768 - - [[ ! -s "$SOCK_REPLY_FILE" ]] && break - cat "$SOCK_REPLY_FILE" >> "$sock_reply_file2" - mv "$sock_reply_file2" "$SOCK_REPLY_FILE" - foo="$(wc -c "$SOCK_REPLY_FILE")" - response_len="${foo% *}" - done - fi - fi - - debugme echo "reading server hello... " - if [[ "$DEBUG" -ge 4 ]]; then - hexdump -C "$SOCK_REPLY_FILE" | head -6 - tmln_out - fi - - parse_sslv2_serverhello "$SOCK_REPLY_FILE" "$parse_complete" - ret=$? - - close_socket 5 - tmpfile_handle ${FUNCNAME[0]}.dd $SOCK_REPLY_FILE - return $ret -} - - -# arg1: supported groups extension -# arg2: "all" - process full response (including Certificate and certificate_status handshake messages) -# "ephemeralkey" - extract the server's ephemeral key (if any) -# Given the supported groups extension, create a key_share extension that includes a key share for -# each group listed in the supported groups extension. -generate_key_share_extension() { - local supported_groups - local -i i len supported_groups_len group - local extn_len list_len - local key_share key_shares="" - local -i nr_key_shares=0 - - supported_groups="${1//\\x/}" - [[ "${supported_groups:0:4}" != "000a" ]] && return 1 - - supported_groups_len=${#supported_groups} - [[ $supported_groups_len -lt 16 ]] && return 1 - - len=2*$(hex2dec "${supported_groups:4:4}") - [[ $len+8 -ne $supported_groups_len ]] && return 1 - - len=2*$(hex2dec "${supported_groups:8:4}") - [[ $len+12 -ne $supported_groups_len ]] && return 1 - - for (( i=12; i=0; i=i-1 )); do - if [[ 0x$i -eq 4 ]]; then - # FIXME: The ClientHello currently advertises support for various - # draft versions of TLSv1.3. Eventually it should only advertise - # support for the final version (0304). - if [[ "$KEY_SHARE_EXTN_NR" == 33 ]]; then - extension_supported_versions+=", 03, 04, 7f, 1c, 7f, 1b, 7f, 1a, 7f, 19, 7f, 18, 7f, 17" - else - extension_supported_versions+=", 7f, 16, 7f, 15, 7f, 14, 7f, 13, 7f, 12" - fi - else - extension_supported_versions+=", 03, $(printf "%02x" $i)" - fi - done - [[ -n "$all_extensions" ]] && all_extensions+="," - # FIXME: Adjust the lengths ("+15" and "+14") when the draft versions of TLSv1.3 are removed. - if [[ "$KEY_SHARE_EXTN_NR" == 33 ]]; then - all_extensions+="00, 2b, 00, $(printf "%02x" $((2*0x$tls_low_byte+15))), $(printf "%02x" $((2*0x$tls_low_byte+14)))$extension_supported_versions" - else - all_extensions+="00, 2b, 00, $(printf "%02x" $((2*0x$tls_low_byte+11))), $(printf "%02x" $((2*0x$tls_low_byte+10)))$extension_supported_versions" - fi - fi - - # There does not seem to be any reason to include this extension. However, it appears that - # OpenSSL, Firefox, and Chrome include it in TLS 1.3 ClientHello messages, and there is at - # least one server that will fail the connection if it is absent - # (see https://github.com/drwetter/testssl.sh/issues/990). - if [[ "0x$tls_low_byte" -ge 0x04 ]] && [[ ! "$extra_extensions_list" =~ \ 002d\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extn_psk_mode" - fi - - if [[ ! "$extra_extensions_list" =~ \ 0023\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extension_session_ticket" - fi - - # If the ClientHello will include the ALPN extension, then don't include the NPN extension. - if [[ ! "$extra_extensions_list" =~ \ 3374\ ]] && [[ ! "$extra_extensions_list" =~ \ 0010\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extension_next_protocol" - fi - - # RFC 5246 says that clients MUST NOT offer the signature algorithms - # extension if they are offering TLS versions prior to 1.2. - if [[ "0x$tls_low_byte" -ge 0x03 ]] && [[ ! "$extra_extensions_list" =~ \ 000d\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extension_signature_algorithms" - fi - - if [[ -n "$extension_supported_groups" ]] && [[ ! "$extra_extensions_list" =~ \ 000a\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extension_supported_groups" - fi - - if [[ -n "$extensions_key_share" ]] && [[ ! "$extra_extensions_list" =~ \ 00$KEY_SHARE_EXTN_NR\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extensions_key_share" - fi - - if [[ -n "$extension_supported_point_formats" ]] && [[ ! "$extra_extensions_list" =~ \ 000b\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extension_supported_point_formats" - fi - - if [[ "0x$tls_low_byte" -ge 0x04 ]] && [[ ! "$extra_extensions_list" =~ \ 001b\ ]]; then - # If the response needs to be decrypted, then indicate support - # for ZLIB certificate compression if $OPENSSL can decompress - # the result. If the response does not need to be decrypted, - # then indicate support for all certificate compression methods, - # as the response does not need to be decompressed. - if [[ "$process_full" =~ all ]]; then - if "$HAS_ZLIB"; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="00,1b,00,03,02,00,01" - fi - else - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="00,1b,00,07,06,00,01,00,02,00,03" - fi - fi - - if [[ -n "$extra_extensions" ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extra_extensions" - fi - - # Make sure that a non-empty extension goes last (either heartbeat or padding). - # See PR #792 and https://www.ietf.org/mail-archive/web/tls/current/msg19720.html. - if [[ ! "$extra_extensions_list" =~ \ 000f\ ]]; then - [[ -n "$all_extensions" ]] && all_extensions+="," - all_extensions+="$extension_heartbeat" - fi - - code2network "$all_extensions" # convert extensions - all_extensions="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next - len_extension=${#all_extensions} - len_extension+=2 - len_extension=$len_extension/4 - len_extension_hex=$(printf "%02x\n" $len_extension) - - # If the length of the Client Hello would be between 256 and 511 bytes, - # then add a padding extension (see RFC 7685) - len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) - "$offer_compression" && len_all+=2 - [[ 0x$tls_low_byte -gt 0x03 ]] && len_all+=32 # TLSv1.3 ClientHello includes a 32-byte session id - if [[ $len_all -ge 256 ]] && [[ $len_all -le 511 ]] && [[ ! "$extra_extensions_list" =~ \ 0015\ ]]; then - if [[ $len_all -ge 508 ]]; then - len_padding_extension=1 # Final extension cannot be empty: see PR #792 - else - len_padding_extension=$((508 - len_all)) - fi - len_padding_extension_hex=$(printf "%02x\n" $len_padding_extension) - len2twobytes "$len_padding_extension_hex" - all_extensions+="\\x00\\x15\\x${LEN_STR:0:2}\\x${LEN_STR:4:2}${padding_bytes:0:$((4*len_padding_extension))}" - len_extension=$len_extension+$len_padding_extension+0x4 - len_extension_hex=$(printf "%02x\n" $len_extension) - elif [[ ! "$extra_extensions_list" =~ \ 0015\ ]] && [[ $((len_all%256)) -eq 10 || $((len_all%256)) -eq 14 ]]; then - # Some servers fail if the length of the ClientHello is 522, 778, 1034, 1290, ... bytes. - # A few servers also fail if the length is 526, 782, 1038, 1294, ... bytes. - # So, if the ClientHello would be one of these length, add a 5-byte padding extension. - all_extensions+="\\x00\\x15\\x00\\x01\\x00" - len_extension+=5 - len_extension_hex=$(printf "%02x\n" $len_extension) - fi - len2twobytes "$len_extension_hex" - all_extensions=" - ,$LEN_STR # first the len of all extensions. - ,$all_extensions" - fi - - if [[ 0x$tls_low_byte -gt 0x03 ]]; then - # TLSv1.3 calls for sending a random 32-byte session id in middlebox compatibility mode. - session_id="20,44,b8,92,56,af,74,52,9e,d8,cf,52,14,c8,af,d8,34,0b,e7,7f,eb,86,01,84,50,5d,e4,a1,6a,09,3b,bf,6e" - len_session_id=32 - else - session_id="00" - len_session_id=0 - fi - - # RFC 3546 doesn't specify SSLv3 to have SNI, openssl just ignores the switch if supplied - if [[ "$tls_low_byte" == 00 ]]; then - len_all=$((0x$len_ciph_suites + len_session_id + 0x27)) - else - len_all=$((0x$len_ciph_suites + len_session_id + 0x27 + 0x$len_extension_hex + 0x2)) - fi - "$offer_compression" && len_all+=2 - len2twobytes $(printf "%02x\n" $len_all) - len_client_hello_word="$LEN_STR" - #[[ $DEBUG -ge 3 ]] && echo $len_client_hello_word - - if [[ "$tls_low_byte" == 00 ]]; then - len_all=$((0x$len_ciph_suites + len_session_id + 0x2b)) - else - len_all=$((0x$len_ciph_suites + len_session_id + 0x2b + 0x$len_extension_hex + 0x2)) - fi - "$offer_compression" && len_all+=2 - len2twobytes $(printf "%02x\n" $len_all) - len_all_word="$LEN_STR" - #[[ $DEBUG -ge 3 ]] && echo $len_all_word - - # if we have SSLv3, the first occurrence of TLS protocol -- record layer -- is SSLv3, otherwise TLS 1.0, - # except in the case of a second ClientHello in TLS 1.3, in which case it is TLS 1.2. - [[ $tls_low_byte == "00" ]] && tls_word_reclayer="03, 00" - - [[ 0x$tls_legacy_version -ge 0x04 ]] && tls_legacy_version="03" - - if "$offer_compression"; then - # See https://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml#comp-meth-ids-2 - compression_methods="03,01,40,00" # Offer NULL, DEFLATE, and LZS compression - else - compression_methods="01,00" # Only offer NULL compression (0x00) - fi - - TLS_CLIENT_HELLO=" - # TLS header ( 5 bytes) - ,16, $tls_word_reclayer # TLS Version: in wireshark this is always 01 for TLS 1.0-1.2 - ,$len_all_word # Length <--- - # Handshake header: - ,01 # Type (x01 for ClientHello) - ,00, $len_client_hello_word # Length ClientHello - ,03, $tls_legacy_version # TLS version ClientHello - ,54, 51, 1e, 7a # Unix time since see www.moserware.com/2009/06/first-few-milliseconds-of-https.html - ,de, ad, be, ef # Random 28 bytes - ,31, 33, 07, 00, 00, 00, 00, 00 - ,cf, bd, 39, 04, cc, 16, 0b, 85 - ,03, 90, 9f, 77, 04, 33, d4, de - ,$session_id - ,$len_ciph_suites_word # Cipher suites length - ,$cipher_suites - ,$compression_methods" - - if "$new_socket"; then - fd_socket 5 || return 6 - fi - - debugme echo -n "sending client hello... " - socksend_clienthello "$TLS_CLIENT_HELLO$all_extensions" $USLEEP_SND - - if [[ "$tls_low_byte" -gt 0x03 ]]; then - TLS_CLIENT_HELLO="$(tolower "$NW_STR")" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x0\\/\\x00\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x1\\/\\x01\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x2\\/\\x02\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x3\\/\\x03\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x4\\/\\x04\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x5\\/\\x05\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x6\\/\\x06\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x7\\/\\x07\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x8\\/\\x08\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x9\\/\\x09\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\xa\\/\\x0a\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\xb\\/\\x0b\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\xc\\/\\x0c\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\xd\\/\\x0d\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\xe\\/\\x0e\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\xf\\/\\x0f\\}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO//\\x/}" - TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO:10}" - fi - - return 0 -} - -# arg1: The original ClientHello -# arg2: The server's response -# Return 0 if the response is not a HelloRetryRequest. -# Return 1 if the response is a malformed HelloRetryRequest or if a new ClientHello cannot be sent. -# Return 2 if the response is a HelloRetryRequest, and sending a new ClientHello succeeded. -# Return 6 if the response is a HelloRetryRequest, and sending a new ClientHello failed. -resend_if_hello_retry_request() { - local original_clienthello="$1" - local tls_hello_ascii="$2" - local msg_type server_version cipher_suite rfc_cipher_suite - local key_share="" new_key_share="" cookie="" second_clienthello data="" - local -i i j msg_len tls_hello_ascii_len sid_len - local -i extns_offset hrr_extns_len len_extn - local extn_type - local sha256_hrr="CF21AD74E59A6111BE1D8C021E65B891C2A211167ABB8C5E079E09E2C8A8339C" - - tls_hello_ascii_len=${#tls_hello_ascii} - # A HelloRetryRequest is at least 13 bytes long - [[ $tls_hello_ascii_len -lt 26 ]] && return 0 - # A HelloRetryRequest is a handshake message (16) with a major record version of 03. - [[ "${tls_hello_ascii:0:4}" != 1603 ]] && return 0 - msg_type="${tls_hello_ascii:10:2}" - if [[ "$msg_type" == 02 ]]; then - # A HRR is a ServerHello with a Random value equal to the - # SHA-256 hash of "HelloRetryRequest" - [[ $tls_hello_ascii_len -lt 76 ]] && return 0 - [[ "${tls_hello_ascii:22:64}" != $sha256_hrr ]] && return 0 - elif [[ "$msg_type" != 06 ]]; then - # The handshake type for hello_retry_request in draft versions was 06. - return 0 - fi - - # This appears to be a HelloRetryRequest message. - debugme echo "reading hello retry request... " - if [[ "$DEBUG" -ge 4 ]]; then - hexdump -C $SOCK_REPLY_FILE | head -6 - echo - [[ "$DEBUG" -ge 5 ]] && echo "$tls_hello_ascii" # one line without any blanks - fi - - # Check the length of the handshake message - msg_len=2*$(hex2dec "${tls_hello_ascii:6:4}") - if [[ $msg_len -gt $tls_hello_ascii_len-10 ]]; then - debugme echo "malformed HelloRetryRequest" - return 1 - fi - # The HelloRetryRequest message may be followed by something - # else (e.g., a change cipher spec message). Ignore anything - # that follows. - tls_hello_ascii_len=$msg_len+10 - - # Check the length of the HelloRetryRequest message. - msg_len=2*$(hex2dec "${tls_hello_ascii:12:6}") - if [[ $msg_len -ne $tls_hello_ascii_len-18 ]]; then - debugme echo "malformed HelloRetryRequest" - return 1 - fi - - if [[ "$msg_type" == 06 ]]; then - server_version="${tls_hello_ascii:18:4}" - if [[ 0x$server_version -ge 0x7f13 ]]; then - # Starting with TLSv1.3 draft 19, a HelloRetryRequest is at least 15 bytes long - [[ $tls_hello_ascii_len -lt 30 ]] && return 0 - cipher_suite="${tls_hello_ascii:22:2},${tls_hello_ascii:24:2}" - extns_offset=26 - else - extns_offset=22 - fi - else - sid_len=2*$(hex2dec "${tls_hello_ascii:86:2}") - i=88+$sid_len - j=90+$sid_len - cipher_suite="${tls_hello_ascii:i:2},${tls_hello_ascii:j:2}" - extns_offset=94+$sid_len - fi - - # Check the length of the extensions. - hrr_extns_len=2*$(hex2dec "${tls_hello_ascii:extns_offset:4}") - if [[ $hrr_extns_len -ne $tls_hello_ascii_len-$extns_offset-4 ]]; then - debugme echo "malformed HelloRetryRequest" - return 1 - fi - - # Parse HelloRetryRequest extensions - for (( i=extns_offset+4; i < tls_hello_ascii_len; i+=8+len_extn )); do - extn_type="${tls_hello_ascii:i:4}" - j=$i+4 - len_extn=2*$(hex2dec "${tls_hello_ascii:j:4}") - j+=4 - if [[ $len_extn -gt $tls_hello_ascii_len-$j ]]; then - debugme echo "malformed HelloRetryRequest" - return 1 - fi - if [[ "$extn_type" == 002C ]]; then - # If the HRR includes a cookie extension, then it needs to be - # included in the next ClientHello. - j=8+$len_extn - cookie="${tls_hello_ascii:i:j}" - elif [[ "$extn_type" == 00$KEY_SHARE_EXTN_NR ]]; then - # If the HRR includes a key_share extension, then it specifies the - # group to be used in the next ClientHello. So, create a key_share - # extension that specifies this group. - if [[ $len_extn -ne 4 ]]; then - debugme echo "malformed key share extension in HelloRetryRequest" - return 1 - fi - key_share="${tls_hello_ascii:j:4}" - new_key_share="$(generate_key_share_extension "000a00040002$key_share" "ephemeralkey")" - [[ $? -ne 0 ]] && return 1 - [[ -z "$new_key_share" ]] && return 1 - new_key_share="${new_key_share//,/}" - elif [[ "$extn_type" == 002B ]]; then - if [[ $len_extn -ne 4 ]]; then - debugme echo "malformed supported versions extension in HelloRetryRequest" - return 1 - fi - server_version="${tls_hello_ascii:j:4}" - fi - done - - if [[ $DEBUG -ge 3 ]]; then - echo "TLS message fragments:" - echo " tls_protocol (reclyr): 0x${tls_hello_ascii:2:4}" - echo " tls_content_type: 0x16 (handshake)" - echo " msg_len: $(hex2dec "${tls_hello_ascii:6:4}")" - echo - echo "TLS handshake message:" - echo -n " handshake type: 0x$msg_type " - case "$msg_type" in - 02) echo "(hello_retry_request formatted as server_hello)" ;; - 06) echo "(hello_retry_request)" ;; - esac - echo " msg_len: $(hex2dec "${tls_hello_ascii:12:6}")" - echo - echo "TLS hello retry request message:" - echo " server version: $server_version" - if [[ "$server_version" == 0304 ]] || [[ 0x$server_version -ge 0x7f13 ]]; then - echo -n " cipher suite: $cipher_suite" - if [[ $TLS_NR_CIPHERS -ne 0 ]]; then - if [[ "${cipher_suite:0:2}" == "00" ]]; then - rfc_cipher_suite="$(show_rfc_style "x${cipher_suite:3:2}")" - else - rfc_cipher_suite="$(show_rfc_style "x${cipher_suite:0:2}${cipher_suite:3:2}")" - fi - elif "$HAS_CIPHERSUITES"; then - rfc_cipher_suite="$($OPENSSL ciphers -V -ciphersuites "$TLS13_OSSL_CIPHERS" 'ALL:COMPLEMENTOFALL' | grep -i " 0x${cipher_suite:0:2},0x${cipher_suite:3:2} " | awk '{ print $3 }')" - else - rfc_cipher_suite="$($OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL' | grep -i " 0x${cipher_suite:0:2},0x${cipher_suite:3:2} " | awk '{ print $3 }')" - fi - if [[ -n "$rfc_cipher_suite" ]]; then - echo " ($rfc_cipher_suite)" - else - echo "" - fi - fi - [[ -n "$key_share" ]] && echo " key share: 0x$key_share" - [[ -n "$cookie" ]] && echo " cookie: $cookie" - fi - - # Starting with TLSv1.3 draft 24, the second ClientHello should specify a record layer version of 0x0303 - if [[ "$server_version" == 0304 ]] || [[ 0x$server_version -ge 0x7f18 ]]; then - original_clienthello="160303${original_clienthello:6}" - fi - - if [[ "$server_version" == 0304 ]] || [[ 0x$server_version -ge 0x7f16 ]]; then - # Send a dummy change cipher spec for middlebox compatibility. - debugme echo -en "\nsending dummy change cipher spec... " - socksend ", x14, x03, x03 ,x00, x01, x01" 0 - fi - debugme echo -en "\nsending second client hello... " - second_clienthello="$(modify_clienthello "$original_clienthello" "$new_key_share" "$cookie")" - TLS_CLIENT_HELLO="${second_clienthello:10}" - msg_len=${#second_clienthello} - for (( i=0; i < msg_len; i+=2 )); do - data+=", ${second_clienthello:i:2}" - done - debugme echo -n "sending client hello... " - socksend_clienthello "$data" $USLEEP_SND - sockread 32768 - return 2 -} - -# arg1: TLS version low byte -# (00: SSLv3, 01: TLS 1.0, 02: TLS 1.1, 03: TLS 1.2) -# arg2: (optional) list of cipher suites -# arg3: (optional): "all" - process full response (including Certificate and certificate_status handshake messages) -# "all+" - same as "all", but do not offer any curves with TLSv1.3 that are not supported by -# $OPENSSL, since response MUST be decrypted. -# "ephemeralkey" - extract the server's ephemeral key (if any) -# arg4: (optional) additional request extensions -# arg5: (optional) "true" if ClientHello should advertise compression methods other than "NULL" -# arg6: (optional) "false" if the connection should not be closed before the function returns. -# return: 0: successful connect | 1: protocol or cipher not available | 2: as (0) but downgraded -# 6: couldn't open socket | 7: couldn't open temp file -tls_sockets() { - local -i ret=0 - local -i save=0 - local lines - local tls_low_byte - local cipher_list_2send - local sock_reply_file2 sock_reply_file3 - local tls_hello_ascii next_packet post_finished_msg="" - local clienthello1 original_clienthello hrr="" - local process_full="$3" offer_compression=false skip=false - local close_connection=true include_headers=true - local -i i len msg_len tag_len hello_done=0 seq_num=0 - local cipher="" tls_version handshake_secret="" res - local initial_msg_transcript msg_transcript finished_msg aad="" data="" plaintext - local handshake_traffic_keys key iv finished_key - local master_secret master_traffic_keys - - APP_TRAF_KEY_INFO="" - [[ "$5" == true ]] && offer_compression=true - [[ "$6" == false ]] && close_connection=false - if [[ "$process_full" == all+ ]] && [[ -s "$TEMPDIR/$NODEIP.parse_tls13_new_session_ticket.txt" ]]; then - rm "$TEMPDIR/$NODEIP.parse_tls13_new_session_ticket.txt" - fi - tls_low_byte="$1" - if [[ -n "$2" ]]; then # use supplied string in arg2 if there is one - cipher_list_2send="$2" - else # otherwise use std ciphers then - if [[ "$tls_low_byte" == 03 ]]; then - cipher_list_2send="$TLS12_CIPHER" - else - cipher_list_2send="$TLS_CIPHER" - fi - fi - code2network "$(tolower "$cipher_list_2send")" # convert CIPHER_SUITES to a "standardized" format - cipher_list_2send="$NW_STR" - - debugme echo -en "\nsending client hello... " - prepare_tls_clienthello "$tls_low_byte" "$cipher_list_2send" "$process_full" "$4" "$offer_compression" - ret=$? # 6 means opening socket didn't succeed, e.g. timeout - - # if sending didn't succeed we don't bother - if [[ $ret -eq 0 ]]; then - clienthello1="$TLS_CLIENT_HELLO" - sockread 32768 - "$TLS_DIFFTIME_SET" && TLS_NOW=$(LC_ALL=C date "+%s") - - tls_hello_ascii=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") - tls_hello_ascii="${tls_hello_ascii%%[!0-9A-F]*}" - tls_hello_ascii="${tls_hello_ascii%%140303000101}" - - # Check if the response is a HelloRetryRequest. - original_clienthello="160301$(printf "%04x" "${#clienthello1}")$clienthello1" - resend_if_hello_retry_request "$original_clienthello" "$tls_hello_ascii" - ret=$? - if [[ $ret -eq 2 ]]; then - hrr="${tls_hello_ascii:10}" - tls_hello_ascii=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") - tls_hello_ascii="${tls_hello_ascii%%[!0-9A-F]*}" - elif [[ $ret -eq 1 ]] || [[ $ret -eq 6 ]]; then - close_socket 5 - TMPFILE=$SOCK_REPLY_FILE - tmpfile_handle ${FUNCNAME[0]}.dd - return $ret - fi - - # The server's response may span more than one packet. If only the - # first part of the response needs to be processed, this isn't an - # issue. However, if the entire response needs to be processed or - # if the ephemeral key is needed (which comes last for TLS 1.2 and - # below), then we need to check if response appears to be complete, - # and if it isn't then try to get another packet from the server. - if [[ "$process_full" =~ all ]] || [[ "$process_full" == ephemeralkey ]]; then - hello_done=1; skip=true - fi - for (( 1 ; hello_done==1; 1 )); do - if ! "$skip"; then - if [[ $DEBUG -ge 1 ]]; then - sock_reply_file2=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 - mv "$SOCK_REPLY_FILE" "$sock_reply_file2" - fi - - debugme echo -n "requesting more server hello data... " - socksend "" $USLEEP_SND - sockread 32768 - - next_packet=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") - next_packet="${next_packet%%[!0-9A-F]*}" - - if [[ ${#next_packet} -eq 0 ]]; then - # This shouldn't be necessary. However, it protects against - # getting into an infinite loop if the server has nothing - # left to send and check_tls_serverhellodone doesn't - # correctly catch it. - [[ $DEBUG -ge 1 ]] && mv "$sock_reply_file2" "$SOCK_REPLY_FILE" - hello_done=0 - else - tls_hello_ascii+="$next_packet" - if [[ $DEBUG -ge 1 ]]; then - sock_reply_file3=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 - mv "$SOCK_REPLY_FILE" "$sock_reply_file3" - mv "$sock_reply_file2" "$SOCK_REPLY_FILE" - cat "$sock_reply_file3" >> "$SOCK_REPLY_FILE" - rm "$sock_reply_file3" - fi - fi - fi - skip=false - if [[ $hello_done -eq 1 ]]; then - res="$(check_tls_serverhellodone "$tls_hello_ascii" "$process_full" "$cipher" "$handshake_secret" "$initial_msg_transcript")" - hello_done=$? - if [[ "$hello_done" -eq 0 ]] && [[ -n "$res" ]]; then - read -r msg_transcript tls_hello_ascii post_finished_msg <<< "$res" - if [[ -n "$post_finished_msg" ]]; then - # Determine TLS version - tls_version="$DETECTED_TLS_VERSION" - if [[ "${TLS_SERVER_HELLO:8:3}" == 7F1 ]]; then - tls_version="${TLS_SERVER_HELLO:8:4}" - elif [[ "$TLS_SERVER_HELLO" =~ 002B00027F1[0-9A-F] ]]; then - tls_version="${BASH_REMATCH:8:4}" - fi - [[ "${tls_version:0:2}" == 7F ]] && [[ 0x${tls_version:2:2} -lt 25 ]] && include_headers=false - - # Compute application traffic keys and IVs. - master_secret="$(derive-master-secret "$cipher" "$handshake_secret")" - master_traffic_keys="$(derive-application-traffic-keys "$cipher" "$master_secret" "$msg_transcript" client)" - APP_TRAF_KEY_INFO="$master_traffic_keys 0" - master_traffic_keys="$(derive-application-traffic-keys "$cipher" "$master_secret" "$msg_transcript" server)" - read -r key iv finished_key <<< "$master_traffic_keys" - while true; do - len=${#post_finished_msg} - [[ $len -ge 10 ]] || break - [[ "${post_finished_msg:0:5}" == 17030 ]] || break - msg_len=$((2*0x${post_finished_msg:6:4})) - [[ $len -ge $((msg_len+10)) ]] || break - aad="${post_finished_msg:0:10}" - "$include_headers" || aad="" - plaintext="$(sym-decrypt "$cipher" "$key" "$(get-nonce "$iv" "$seq_num")" "${post_finished_msg:10:msg_len}" "$aad")" - - # Remove zeros from end of plaintext, if any - len=${#plaintext}-2 - while [[ "${plaintext:len:2}" == 00 ]]; do - len=$((len-2)) - done - tls_hello_ascii+="${plaintext:len:2}0301$(printf "%04X" $((len/2)))${plaintext:0:len}" - post_finished_msg="${post_finished_msg:$((msg_len+10))}" - seq_num+=1 - done - APP_TRAF_KEY_INFO="$tls_version $cipher $master_traffic_keys $seq_num $APP_TRAF_KEY_INFO" - fi - tls_hello_ascii="$(toupper "$tls_hello_ascii")" - fi - if [[ "$hello_done" -eq 3 ]]; then - hello_done=1; skip=true - debugme echo "reading server hello..." - parse_tls_serverhello "$tls_hello_ascii" "ephemeralkey" - ret=$? - if [[ "$ret" -eq 0 ]] || [[ "$ret" -eq 2 ]]; then - cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - if [[ -n "$hrr" ]]; then - initial_msg_transcript="$(create-initial-transcript "$cipher" "$clienthello1" "$hrr" "$TLS_CLIENT_HELLO" "$TLS_SERVER_HELLO")" - else - initial_msg_transcript="$(create-initial-transcript "$cipher" "" "" "$TLS_CLIENT_HELLO" "$TLS_SERVER_HELLO")" - fi - handshake_secret="$(derive-handshake-secret "$cipher" "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" - [[ $? -ne 0 ]] && hello_done=2 - else - hello_done=2 - fi - fi - fi - done - - debugme echo "reading server hello..." - if [[ "$DEBUG" -ge 4 ]]; then - hexdump -C $SOCK_REPLY_FILE | head -6 - echo - fi - - parse_tls_serverhello "$tls_hello_ascii" "$process_full" "$cipher_list_2send" - save=$? - if "$close_connection" && [[ $save == 0 ]]; then - send_close_notify "$DETECTED_TLS_VERSION" - fi - - if [[ $DEBUG -ge 2 ]]; then - # see https://secure.wand.net.nz/trac/libprotoident/wiki/SSL - lines=$(count_lines "$(hexdump -C "$SOCK_REPLY_FILE" 2>$ERRFILE)") - tm_out " ($lines lines returned) " - fi - - if ! "$close_connection" && [[ $save == 0 ]] && \ - [[ -n "$handshake_secret" ]] && [[ "$process_full" == all+ ]]; then - tls_version="$DETECTED_TLS_VERSION" - if [[ "${TLS_SERVER_HELLO:8:3}" == 7F1 ]]; then - tls_version="${TLS_SERVER_HELLO:8:4}" - elif [[ "$TLS_SERVER_HELLO" =~ 002B00027F1[0-9A-F] ]]; then - tls_version="${BASH_REMATCH:8:4}" - fi - [[ "${tls_version:0:2}" == 7F ]] && [[ 0x${tls_version:2:2} -lt 25 ]] && include_headers=false - - handshake_traffic_keys="$(derive-handshake-traffic-keys "$cipher" "$handshake_secret" "$initial_msg_transcript" "client")" - read -r key iv finished_key <<< "$handshake_traffic_keys" - if [[ "$cipher" == *SHA256 ]]; then - finished_msg="14000020$(hmac-transcript "-sha256" "$finished_key" "$msg_transcript")" - else - finished_msg="14000030$(hmac-transcript "-sha384" "$finished_key" "$msg_transcript")" - fi - [[ "$cipher" =~ CCM_8 ]] && tag_len=8 || tag_len=16 - aad="170303$(printf "%04X" "$(( ${#finished_msg}/2 + tag_len + 1 ))")" - if "$include_headers"; then - # The header information was added to additional data in TLSv1.3 draft 25. - finished_msg="$(sym-encrypt "$cipher" "$key" "$(get-nonce "$iv" 0)" "${finished_msg}16" "$aad")" - else - finished_msg="$(sym-encrypt "$cipher" "$key" "$(get-nonce "$iv" 0)" "${finished_msg}16" "")" - fi - finished_msg="$aad$finished_msg" - - len=${#finished_msg} - for (( i=0; i < len; i+=2 )); do - data+=", ${finished_msg:i:2}" - done - debugme echo -e "\nsending finished..." - socksend_clienthello "${data}" - sleep $USLEEP_SND - - if [[ -z "$APP_TRAF_KEY_INFO" ]]; then - # Compute application traffic keys and IVs. - master_secret="$(derive-master-secret "$cipher" "$handshake_secret")" - master_traffic_keys="$(derive-application-traffic-keys "$cipher" "$master_secret" "$msg_transcript" server)" - APP_TRAF_KEY_INFO="$tls_version $cipher $master_traffic_keys 0 " - master_traffic_keys="$(derive-application-traffic-keys "$cipher" "$master_secret" "$msg_transcript" client)" - APP_TRAF_KEY_INFO+="$master_traffic_keys 0" - fi - - # Some servers send new session tickets as soon as the handshake is complete. - receive_app_data - if [[ $? -eq 0 ]] && [[ $DEBUG -ge 2 ]]; then - [[ -s $TMPFILE ]] && echo -n "Unexpected response: " && cat "$TMPFILE" - fi - fi - if [[ $DEBUG -ge 2 ]] &&[[ "$process_full" == all+ ]] && [[ -s "$TEMPDIR/$NODEIP.parse_tls13_new_session_ticket.txt" ]]; then - echo -en "\nTicket: " && cat "$TEMPDIR/$NODEIP.parse_tls13_new_session_ticket.txt" - fi - - # determine the return value for higher level, so that they can tell what the result is - if [[ $save -eq 1 ]] || [[ $lines -eq 1 ]]; then - ret=1 # NOT available - elif [[ $save -eq 3 ]]; then - # only for IMAP currently 'a002 NO Starttls' - ret=3 - elif [[ $save -eq 8 ]]; then - # odd return, we just pass this from parse_tls_serverhello() back - ret=8 - elif [[ $save -eq 4 ]]; then - # STARTTLS problem passing back - ret=4 - else - if [[ 03$tls_low_byte -eq $DETECTED_TLS_VERSION ]]; then - ret=0 # protocol available, TLS version returned equal to the one send - else - debugme echo -n "protocol send: 0x03$tls_low_byte, returned: 0x$DETECTED_TLS_VERSION" - ret=2 # protocol NOT available, server downgraded to $DETECTED_TLS_VERSION - fi - fi - debugme echo - else - debugme echo "stuck on sending: $ret" - fi - - "$close_connection" && close_socket 5 - tmpfile_handle ${FUNCNAME[0]}.dd $SOCK_REPLY_FILE - return $ret -} - -# Send application data over a TLS 1.3 channel that has already been created. -send_app_data() { - local plaintext="$1" - local tls_version cipher client_key client_iv server_key server_iv - local aad res data - local -i i client_seq server_seq tag_len len - local include_headers=true - - read -r tls_version cipher server_key server_iv server_seq client_key client_iv client_seq <<< "$APP_TRAF_KEY_INFO" - [[ "${tls_version:0:2}" == 7F ]] && [[ 0x${tls_version:2:2} -lt 25 ]] && include_headers=false - [[ "$cipher" =~ CCM_8 ]] && tag_len=8 || tag_len=16 - - aad="170303$(printf "%04X" "$(( ${#plaintext}/2 + tag_len + 1 ))")" - if "$include_headers"; then - res="$(sym-encrypt "$cipher" "$client_key" "$(get-nonce "$client_iv" $client_seq)" "${plaintext}17" "$aad")" - else - res="$(sym-encrypt "$cipher" "$client_key" "$(get-nonce "$client_iv" $client_seq)" "${plaintext}17" "")" - fi - [[ $? -eq 0 ]] || return 1 - client_seq+=1 - APP_TRAF_KEY_INFO="$tls_version $cipher $server_key $server_iv $server_seq $client_key $client_iv $client_seq" - - res="$aad$res" - len=${#res} - data="" - for (( i=0; i < len; i+=2 )); do - data+=",x${res:i:2}" - done - socksend "$data" $USLEEP_SND -} - -# Receive application data from a TLS 1.3 channel that has already been created. -# arg1: true if only the first block of application data should be decrypted. -# This can save a lot of time if the server sends a lot a data (e.g., a -# big home page), but only the first part of the data is needed. However, -# no further data may be received over this connection as the message -# sequence number will not be correct. -receive_app_data() { - local plaintext="" - local tls_version cipher client_key client_iv server_key server_iv - local aad ciphertext="" res="" data - local -i client_seq server_seq len msg_len - local include_headers=true - local first_block_only=false - - [[ "$1" == true ]] && first_block_only=true - - read -r tls_version cipher server_key server_iv server_seq client_key client_iv client_seq <<< "$APP_TRAF_KEY_INFO" - [[ "${tls_version:0:2}" == 7F ]] && [[ 0x${tls_version:2:2} -lt 25 ]] && include_headers=false - - sleep $USLEEP_REC - while true; do - len=${#ciphertext} - if [[ $len -ge 10 ]]; then - [[ "${ciphertext:0:5}" == 17030 ]] || break - msg_len=$((2*0x${ciphertext:6:4})) - fi - if [[ $len -lt 10 ]] || [[ $len -lt $((msg_len+10)) ]]; then - if "$FAST_SOCKET"; then - res="$(sockread_fast 32768)" - else - sockread 32768 - res="$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE")" - fi - res="${res%%[!0-9A-F]*}" - [[ -z "$res" ]] && break - ciphertext+="$res" - continue - fi - "$include_headers" && aad="${ciphertext:0:10}" || aad="" - data="$(sym-decrypt "$cipher" "$server_key" "$(get-nonce "$server_iv" "$server_seq")" "${ciphertext:10:msg_len}" "$aad")" - [[ $? -eq 0 ]] || return 1 - - len=${#data}-2 - while [[ "${data:len:2}" == 00 ]]; do - len=$((len-2)) - done - content_type="${data:len:2}" - - if [[ "$content_type" == 16 ]] && [[ "${data:0:2}" == 04 ]]; then - # This is a new_session_ticket - parse_tls13_new_session_ticket "$tls_version" "${data:0:len}" - elif [[ "$content_type" == 17 ]]; then - # This really is application data. - plaintext+="${data:0:len}" - "$first_block_only" && break - fi - ciphertext=${ciphertext:$((msg_len+10))} - server_seq+=1 - [[ -z "$ciphertext" ]] && break - done - APP_TRAF_KEY_INFO="$tls_version $cipher $server_key $server_iv $server_seq $client_key $client_iv $client_seq" - hex2binary "$plaintext" > "$TMPFILE" - return 0 -} - - -####### Vulnerabilities follow ####### -# General overview which browser "supports" which vulnerability: -# https://en.wikipedia.org/wiki/Transport_Layer_Security#Web_browsers - -# mainly adapted from https://gist.github.com/takeshixx/10107280 -# -run_heartbleed(){ - local tls_hexcode - local heartbleed_payload - local -i n lines_returned - local append="" - local tls_hello_ascii="" - local jsonID="heartbleed" - local cve="CVE-2014-0160" - local cwe="CWE-119" - local hint="" - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for heartbleed vulnerability " && outln - pr_bold " Heartbleed"; out " ($cve) " - - if [[ "$STARTTLS_PROTOCOL" =~ irc ]]; then - prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" - return 1 - fi - - [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions - if [[ ! "${TLS_EXTENSIONS}" =~ heartbeat ]]; then - pr_svrty_best "not vulnerable (OK)" - outln ", no heartbeat extension" - fileout "$jsonID" "OK" "not vulnerable, no heartbeat extension" "$cve" "$cwe" - return 0 - fi - - if [[ 0 -eq $(has_server_protocol tls1) ]]; then - tls_hexcode="x03, x01" - elif [[ 0 -eq $(has_server_protocol tls1_1) ]]; then - tls_hexcode="x03, x02" - elif [[ 0 -eq $(has_server_protocol tls1_2) ]]; then - tls_hexcode="x03, x03" - elif [[ 0 -eq $(has_server_protocol ssl3) ]]; then - tls_hexcode="x03, x00" - else # no protocol for some reason defined, determine TLS versions offered with a new handshake - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY") >$TMPFILE 2>$ERRFILE =SSLv3): 18030x in case of a heartBEAT reply -- which we take as a positive result - tls_hello_ascii=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") - debugme echo "tls_content_type: ${tls_hello_ascii:0:2}" - debugme echo "tls_protocol: ${tls_hello_ascii:2:4}" - - lines_returned=$(count_lines "$(hexdump -ve '16/1 "%02x " " \n"' "$SOCK_REPLY_FILE")") - debugme echo "lines HB reply: $lines_returned" - - if [[ $DEBUG -ge 3 ]]; then - tmln_out "\nheartbleed reply: " - hexdump -C "$SOCK_REPLY_FILE" | head -20 - [[ $lines_returned -gt 20 ]] && tmln_out "[...]" - tmln_out - fi - - if [[ $lines_returned -gt 1 ]] && [[ "${tls_hello_ascii:0:4}" == 1803 ]]; then - if [[ "$STARTTLS_PROTOCOL" =~ ftp ]]; then - # check possibility of weird vsftpd reply, see #426, despite "1803" seems very unlikely... - if grep -q '500 OOPS' "$SOCK_REPLY_FILE" ; then - append=", successful weeded out vsftpd false positive" - pr_svrty_best "not vulnerable (OK)"; out "$append" - fileout "$jsonID" "OK" "not vulnerable $append" "$cve" "$cwe" - else - out "likely " - pr_svrty_critical "VULNERABLE (NOT ok)" - [[ $DEBUG -lt 3 ]] && tm_out ", use debug >=3 to confirm" - fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" - fi - else - pr_svrty_critical "VULNERABLE (NOT ok)" - fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" - set_grade_cap "F" "Vulnerable to Heartbleed" - fi - else - pr_svrty_best "not vulnerable (OK)" - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - fi - fi - outln - tmpfile_handle ${FUNCNAME[0]}.dd $SOCK_REPLY_FILE - close_socket 5 - return 0 -} - -# helper function -ok_ids(){ - prln_svrty_best "\n ok -- something reset our ccs packets" - return 0 -} - -# see https://www.openssl.org/news/secadv_20140605.txt -# mainly adapted from Ramon de C Valle's C code from https://gist.github.com/rcvalle/71f4b027d61a78c42607 -#FIXME: At a certain point ccs needs to be changed and make use of code2network using a file, then tls_sockets -# -run_ccs_injection(){ - local tls_hexcode ccs_message client_hello byte6 - local -i retval ret=0 - local tls_hello_ascii="" - local jsonID="CCS" - local cve="CVE-2014-0224" - local cwe="CWE-310" - local hint="" - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for CCS injection vulnerability " && outln - pr_bold " CCS"; out " ($cve) " - - if [[ "$STARTTLS_PROTOCOL" =~ irc ]]; then - prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" - return 1 - fi - - if [[ 0 -eq $(has_server_protocol tls1) ]]; then - tls_hexcode="x03, x01" - elif [[ 0 -eq $(has_server_protocol tls1_1) ]]; then - tls_hexcode="x03, x02" - elif [[ 0 -eq $(has_server_protocol tls1_2) ]]; then - tls_hexcode="x03, x03" - elif [[ 0 -eq $(has_server_protocol ssl3) ]]; then - tls_hexcode="x03, x00" - else # no protocol for some reason defined, determine TLS versions offered with a new handshake - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY") >$TMPFILE 2>$ERRFILE RST -# -# 0A: Unexpected message -# 28: Handshake failure - if [[ -z "${tls_hello_ascii:0:12}" ]]; then - # empty reply - pr_svrty_best "not vulnerable (OK)" - if [[ $retval -eq 3 ]]; then - fileout "$jsonID" "OK" "not vulnerable (timed out)" "$cve" "$cwe" - else - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - fi - elif [[ "${tls_hello_ascii:0:4}" == "1503" ]]; then - if [[ ! "${tls_hello_ascii:5:2}" =~ [03|02|01|00] ]]; then - pr_warning "test failed " - out "no proper TLS reply (debug info: protocol sent: 1503${tls_hexcode#x03, x}, reply: ${tls_hello_ascii:0:14}" - fileout "$jsonID" "DEBUG" "test failed, around line $LINENO, debug info (${tls_hello_ascii:0:14})" "$cve" "$cwe" "$hint" - ret=1 - elif [[ "$byte6" == "15" ]]; then - # decryption failed received - pr_svrty_critical "VULNERABLE (NOT ok)" - fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" - set_grade_cap "F" "Vulnerable to CCS injection" - elif [[ "$byte6" == "0A" ]] || [[ "$byte6" == "28" ]]; then - # Unexpected message / Handshake failure received - pr_warning "likely " - out "not vulnerable (OK)" - out " - alert description type: $byte6" - fileout "$jsonID" "WARN" "probably not vulnerable but received 0x${byte6} instead of 0x15" "$cve" "$cwe" "$hint" - elif [[ "$byte6" == "14" ]]; then - # bad_record_mac -- this is not "not vulnerable" - out "likely " - pr_svrty_critical "VULNERABLE (NOT ok)" - out ", suspicious \"bad_record_mac\" ($byte6)" - fileout "$jsonID" "CRITICAL" "likely VULNERABLE" "$cve" "$cwe" "$hint" - else - # other errors, see https://tools.ietf.org/html/rfc5246#section-7.2 - out "likely " - pr_svrty_critical "VULNERABLE (NOT ok)" - out ", suspicious error code \"$byte6\" returned. Please report" - fileout "$jsonID" "CRITICAL" "likely VULNERABLE with $byte6" "$cve" "$cwe" "$hint" - fi - elif [[ $STARTTLS_PROTOCOL == "mysql" ]] && [[ "${tls_hello_ascii:14:12}" == "233038533031" ]]; then - # MySQL community edition (yaSSL) returns a MySQL error instead of a TLS Alert - # Error: #08S01 Bad handshake - pr_svrty_best "not vulnerable (OK)" - out ", looks like MySQL community edition (yaSSL)" - fileout "$jsonID" "OK" "not vulnerable (MySQL community edition (yaSSL) detected)" "$cve" "$cwe" - elif [[ "$byte6" == [0-9a-f][0-9a-f] ]] && [[ "${tls_hello_ascii:2:2}" != "03" ]]; then - pr_warning "test failed" - out ", probably read buffer too small (${tls_hello_ascii:0:14})" - fileout "$jsonID" "DEBUG" "test failed, probably read buffer too small (${tls_hello_ascii:0:14})" "$cve" "$cwe" "$hint" - ret=1 - else - pr_warning "test failed " - out "around line $LINENO (debug info: ${tls_hello_ascii:0:12},$byte6)" - fileout "$jsonID" "DEBUG" "test failed, around line $LINENO, debug info (${tls_hello_ascii:0:12},$byte6)" "$cve" "$cwe" "$hint" - ret=1 - fi - outln - - tmpfile_handle ${FUNCNAME[0]}.dd $SOCK_REPLY_FILE - close_socket 5 - return $ret -} - -sub_session_ticket_tls() { - local tls_proto="$1" - local sessticket_tls="" - #FIXME: we likely have done this already before (either @ run_server_defaults() or at least the output - # from a previous handshake) --> would save 1x connect. We have TLS_TICKET but not yet the ticket itself #FIXME - #ATTENTION: we DO NOT use SNI here as we assume ticketbleed is a vulnerability of the TLS stack. If we'd do SNI here, we'd also need - # it in the ClientHello of run_ticketbleed() otherwise the ticket will be different and the whole thing won't work! - # - sessticket_tls="$($OPENSSL s_client $(s_client_options "$BUGS $tls_proto $PROXY -connect $NODEIP:$PORT") $ERRFILE | awk '/TLS session ticket:/,/^$/' | awk '!/TLS session ticket/')" - sessticket_tls="$(sed -e 's/^.* - /x/g' -e 's/ .*$//g' <<< "$sessticket_tls" | tr '\n' ',')" - sed -e 's/ /,x/g' -e 's/-/,x/g' <<< "$sessticket_tls" - -} - - -# see https://blog.filippo.io/finding-ticketbleed/ | https://filippo.io/ticketbleed/ -run_ticketbleed() { - local tls_hexcode tls_proto="" - local session_tckt_tls="" - local -i len_ch=300 # fixed len of prepared clienthello below - local sid="x00,x0B,xAD,xC0,xDE,x00," # some arbitrary bytes - local len_sid="$(( ${#sid} / 4))" - local xlen_sid="$(dec02hex $len_sid)" - local -i len_tckt_tls=0 nr_sid_detected=0 - local xlen_tckt_tls="" xlen_handshake_record_layer="" xlen_handshake_ssl_layer="" - local -i len_handshake_record_layer=0 - local i - local -a memory sid_detected - local early_exit=true - local -i ret=0 - local jsonID="ticketbleed" - local cve="CVE-2016-9244" - local cwe="CWE-200" - local hint="" - - [[ -n "$STARTTLS" ]] && return 0 - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for Ticketbleed vulnerability " && outln - pr_bold " Ticketbleed"; out " ($cve), experiment. " - - if [[ "$SERVICE" != HTTP ]] && [[ "$CLIENT_AUTH" != required ]]; then - outln "(applicable only for HTTPS)" - fileout "$jsonID" "INFO" "not applicable, not HTTP" "$cve" "$cwe" - return 0 - fi - - # highly unlikely that it is NOT supported. We may loose time here but it's more solid - [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions - if [[ ! "${TLS_EXTENSIONS}" =~ "session ticket" ]]; then - pr_svrty_best "not vulnerable (OK)" - outln ", no session ticket extension" - fileout "$jsonID" "OK" "no session ticket extension" "$cve" "$cwe" - return 0 - fi - - if [[ 0 -eq $(has_server_protocol tls1) ]]; then - tls_hexcode="x03, x01"; tls_proto="-tls1" - elif [[ 0 -eq $(has_server_protocol tls1_1) ]]; then - tls_hexcode="x03, x02"; tls_proto="-tls1_1" - elif [[ 0 -eq $(has_server_protocol tls1_2) ]]; then - tls_hexcode="x03, x03"; tls_proto="-tls1_2" - elif [[ 0 -eq $(has_server_protocol ssl3) ]]; then - tls_hexcode="x03, x00"; tls_proto="-ssl3" - else # no protocol for some reason defined, determine TLS versions offered with a new handshake - "$HAS_TLS13" && tls_proto="-no_tls1_3" - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS $tls_proto -connect $NODEIP:$PORT $PROXY") >$TMPFILE 2>$ERRFILE $TEMPDIR/${FUNCNAME[0]}.tls_hello_ascii${i}.txt - else - ret=1 - pr_warning "test failed" - out " around line $LINENO (debug info: ${tls_hello_ascii:0:2}, ${tls_hello_ascii:2:10})" - fileout "$jsonID" "DEBUG" "test failed, around $LINENO (debug info: ${tls_hello_ascii:0:2}, ${tls_hello_ascii:2:10})" "$cve" "$cwe" - send_close_notify "${tls_hello_ascii:18:4}" - close_socket 5 - break - fi - send_close_notify "${tls_hello_ascii:18:4}" - close_socket 5 - done - - if ! "$early_exit"; then - # here we test the replies if a TLS server hello was received >1x - for i in 1 2 3 ; do - if [[ "${sid_detected[i]}" =~ $sid_input ]]; then - # was our faked TLS SID returned? - nr_sid_detected+=1 - fi - done - if [[ $nr_sid_detected -eq 3 ]]; then - if [[ ${memory[1]} != ${memory[2]} ]] && [[ ${memory[2]} != ${memory[3]} ]]; then - pr_svrty_critical "VULNERABLE (NOT ok)" - fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" - set_grade_cap "F" "Vulnerable to Ticketbleed" - else - pr_svrty_best "not vulnerable (OK)" - out ", session IDs were returned but potential memory fragments do not differ" - fileout "$jsonID" "OK" "not vulnerable, returned potential memory fragments do not differ" "$cve" "$cwe" - fi - else - if [[ "$DEBUG" -ge 2 ]]; then - echo - pr_warning "test failed, non reproducible results!" - else - pr_warning "test failed, non reproducible results!" - out " Please run again w \"--debug=2\" (# of faked TLS SIDs detected: $nr_sid_detected)" - fi - fileout "$jsonID" "DEBUG" "test failed, non reproducible results. $nr_sid_detected TLS Session IDs $nr_sid_detected, ${sid_detected[1]},${sid_detected[2]},${sid_detected[3]}" "$cve" "$cwe" - ret=1 - fi - fi - outln - return $ret -} - -# Overview @ http://www.exploresecurity.com/wp-content/uploads/custom/SSL_manual_cheatsheet.html -# -run_renego() { - local legacycmd="" proto="$OPTIMAL_PROTO" - local sec_renego sec_client_renego - local -i ret=0 - local cve="" - local cwe="CWE-310" - local hint="" - local jsonID="" - local ssl_reneg_attempts=$SSL_RENEG_ATTEMPTS - # SNI is needed here as openssl returns an error if missing - - "$HAS_TLS13" && [[ -z "$proto" ]] && proto="-no_tls1_3" - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for Renegotiation vulnerabilities " && outln - - pr_bold " Secure Renegotiation (RFC 5746) " - jsonID="secure_renego" - - if "$TLS13_ONLY"; then - # https://www.openssl.org/blog/blog/2018/02/08/tlsv1.3/ - pr_svrty_best "not vulnerable (OK)" - [[ $DEBUG -ge 1 ]] && out ", no renegotiation support in TLS 1.3 only servers" - outln - fileout "$jsonID" "OK" "TLS 1.3 only server" "$cve" "$cwe" - else - # first fingerprint for the Line "Secure Renegotiation IS NOT" or "Secure Renegotiation IS " - $OPENSSL s_client $(s_client_options "$proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") 2>&1 $TMPFILE 2>$ERRFILE - if sclient_connect_successful $? $TMPFILE; then - grep -iaq "Secure Renegotiation IS NOT" $TMPFILE - sec_renego=$? # 0= Secure Renegotiation IS NOT supported - # grep -iaq "Secure Renegotiation IS supported" - #FIXME: didn't occur to me yet but why not also to check on "Secure Renegotiation IS supported" - case $sec_renego in - 0) prln_svrty_critical "Not supported / VULNERABLE (NOT ok)" - fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" - set_grade_warning "Secure renegotiation is not supported" - ;; - 1) prln_svrty_best "supported (OK)" - fileout "$jsonID" "OK" "supported" "$cve" "$cwe" - ;; - *) prln_warning "FIXME (bug): $sec_renego" - fileout "$jsonID" "WARN" "FIXME (bug) $sec_renego" "$cve" "$cwe" - ;; - esac - else - prln_warning "OpenSSL handshake didn't succeed" - fileout "$jsonID" "WARN" "OpenSSL handshake didn't succeed" "$cve" "$cwe" - fi - fi - - # FIXME: Basically this can be done with sockets and we might have that information already - # see https://tools.ietf.org/html/rfc5746#section-3.4: 'The client MUST include either an empty "renegotiation_info" - # extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite value in the ClientHello. [..] - # When a ServerHello is received, the client MUST check if it includes the "renegotiation_info" extension: - # If the extension is not present, the server does not support secure renegotiation' - - - pr_bold " Secure Client-Initiated Renegotiation " - jsonID="secure_client_renego" - cve="CVE-2011-1473" - # see: https://blog.qualys.com/ssllabs/2011/10/31/tls-renegotiation-and-denial-of-service-attacks - # https://blog.ivanristic.com/2009/12/testing-for-ssl-renegotiation.html -- head/get doesn't seem to be needed though - # https://archive.fo/20130415224936/http://www.thc.org/thc-ssl-dos/ - # https://vincent.bernat.ch/en/blog/2011-ssl-dos-mitigation - case "$OSSL_VER" in - 0.9.8*) # we need this for Mac OSX unfortunately - case "$OSSL_VER_APPENDIX" in - [a-l]) - prln_local_problem " Your $OPENSSL cannot test this secure renegotiation vulnerability" - fileout "$jsonID" "WARN" "your $OPENSSL cannot test this secure renegotiation vulnerability" "$cve" "$cwe" - return 1 - ;; - [m-z]) - ;; # all ok - esac - ;; - 1.0.1*|1.0.2*) - legacycmd="-legacy_renegotiation" - ;; - 0.9.9*|1.0*|1.1*) - ;; # all ok - esac - - if "$TLS13_ONLY"; then - pr_svrty_best "not vulnerable (OK)" - [[ $DEBUG -ge 1 ]] && out ", no renegotiation support in TLS 1.3 only servers" - outln - fileout "$jsonID" "OK" "not vulnerable, TLS 1.3 only" "$cve" "$cwe" - elif [[ "$CLIENT_AUTH" == required ]]; then - prln_warning "client x509-based authentication prevents this from being tested" - fileout "$jsonID" "WARN" "client x509-based authentication prevents this from being tested" - sec_client_renego=1 - else - # We need up to two tries here, as some LiteSpeed servers don't answer on "R" and block. Thus first try in the background - # msg enables us to look deeper into it while debugging - echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & - wait_kill $! $HEADER_MAXSLEEP - if [[ $? -eq 3 ]]; then - pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out" # it hung - fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe" - sec_client_renego=1 - else - # second try in the foreground as we are sure now it won't hang - echo R | $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE - sec_client_renego=$? - # 0 means client is renegotiating & doesn't return an error --> vuln! - # 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output - if tail -5 $TMPFILE| grep -qa '^closed'; then - # Exemption from above: server closed the connection but return value was zero - # See https://github.com/drwetter/testssl.sh/issues/1725 and referenced issue @haproxy - sec_client_renego=1 - fi - case "$sec_client_renego" in - 0) # We try again if server is HTTP. This could be either a node.js server or something else. - # Mitigations (default values) for: - # - node.js allows 3x R and then blocks. So then 4x should be tested. - # - F5 BIG-IP ADS allows 5x R and then blocks. So then 6x should be tested. - # This way we save a couple seconds as we weeded out the ones which are more robust - # Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS. - if [[ $SERVICE != HTTP ]]; then - pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat" - fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint" - else - (for ((i=0; i < ssl_reneg_attempts; i++ )); do echo R; sleep 1; done) | \ - $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE - case $? in - 0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)" - fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint" - ;; - 1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect within $ssl_reneg_attempts)" - fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" - ;; - *) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)" - fileout "$jsonID" "DEBUG" "FIXME (bug $ssl_reneg_attempts tries) $sec_client_renego" "$cve" "$cwe" - ret=1 - ;; - esac - fi - ;; - 1) - prln_svrty_good "not vulnerable (OK)" - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - ;; - *) - prln_warning "FIXME (bug): $sec_client_renego" - fileout "$jsonID" "DEBUG" "FIXME (bug) $sec_client_renego - Please report" "$cve" "$cwe" - ret=1 - ;; - esac - fi - fi - - #pr_bold " Insecure Client-Initiated Renegotiation " # pre-RFC 5746, CVE-2009-3555 - #jsonID="insecure_client_renego" - # - # https://www.openssl.org/news/vulnerabilities.html#y2009. It can only be tested with OpenSSL <=0.9.8k - # Insecure Client-Initiated Renegotiation is missing ==> sockets. When we complete the handshake ;-) - - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - -run_crime() { - local -i ret=0 sclient_success - local addcmd="" - local cve="CVE-2012-4929" - local cwe="CWE-310" - local hint="" - - # In a nutshell: don't offer TLS/SPDY compression. This tests for CRIME Vulnerability on HTTPS only, - # not SPDY or ALPN (yet). Please note that it is an attack where you need client side control, so in - # regular situations this # means anyway "game over", with or without CRIME. - # - # https://blog.qualys.com/ssllabs/2012/09/14/crime-information-leakage-attack-against-ssltls - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for CRIME vulnerability " && outln - pr_bold " CRIME, TLS " ; out "($cve) " - jsonID="CRIME_TLS" - - if "$TLS13_ONLY"; then - pr_svrty_best "not vulnerable (OK)" - [[ $DEBUG -ge 1 ]] && out ", no compression in TLS 1.3 only servers" - outln - fileout "$jsonID" "OK" "TLS 1.3 only server" "$cve" "$cwe" - return 0 - fi - - if ! "$HAS_ZLIB"; then - if "$SSL_NATIVE"; then - prln_local_problem "$OPENSSL lacks zlib support" - fileout "$jsonID" "WARN" "CRIME, TLS: Not tested. $OPENSSL lacks zlib support" "$cve" "$cwe" - return 1 - else - tls_sockets "03" "$TLS12_CIPHER" "" "" "true" - sclient_success=$? - [[ $sclient_success -eq 2 ]] && sclient_success=0 - [[ $sclient_success -eq 0 ]] && cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE - fi - else - [[ "$OSSL_VER" == 0.9.8* ]] && addcmd="-no_ssl2" - "$HAS_TLS13" && [[ -z "$OPTIMAL_PROTO" ]] && addcmd+=" -no_tls1_3" - $OPENSSL s_client $(s_client_options "$OPTIMAL_PROTO $BUGS -comp $addcmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI") $TMPFILE - sclient_connect_successful $? $TMPFILE - sclient_success=$? - fi - - if [[ $sclient_success -ne 0 ]]; then - pr_warning "test failed (couldn't connect)" - fileout "$jsonID" "WARN" "Check failed, couldn't connect" "$cve" "$cwe" - ret=1 - elif grep -a Compression $TMPFILE | grep -aq NONE >/dev/null; then - pr_svrty_good "not vulnerable (OK)" - if [[ $SERVICE != HTTP ]] && [[ "$CLIENT_AUTH" != required ]]; then - out " (not using HTTP anyway)" - fileout "$jsonID" "OK" "not vulnerable (not using HTTP anyway)" "$cve" "$cwe" - else - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - fi - else - if [[ $SERVICE == HTTP ]] || [[ "$CLIENT_AUTH" == required ]]; then - pr_svrty_high "VULNERABLE (NOT ok)" - fileout "$jsonID" "HIGH" "VULNERABLE" "$cve" "$cwe" "$hint" - else - pr_svrty_medium "VULNERABLE but not using HTTP: probably no exploit known" - fileout "$jsonID" "MEDIUM" "VULNERABLE, but not using HTTP. Probably no exploit known" "$cve" "$cwe" "$hint" - # not clear whether a protocol != HTTP offers the ability to repeatedly modify the input - # which is done e.g. via javascript in the context of HTTP - fi - set_grade_cap "C" "Vulnerable to CRIME" - fi - outln - -# this needs to be re-done i order to remove the redundant check for spdy - - # weed out starttls, spdy-crime is a web thingy -# if [[ "x$STARTTLS" != "x" ]]; then -# echo -# return $ret -# fi - - # weed out non-webports, spdy-crime is a web thingy. there's a catch thoug, you see it? -# case $PORT in -# 25|465|587|80|110|143|993|995|21) -# echo -# return $ret -# esac - -# if "$HAS_NPN"; then -# $OPENSSL s_client -host $NODE -port $PORT -nextprotoneg $NPN_PROTOs $SNI /dev/null >$TMPFILE -# if [[ $? -eq 0 ]]; then -# echo -# pr_bold "CRIME Vulnerability, SPDY " ; outln "($cve): " - -# STR=$(grep Compression $TMPFILE ) -# if echo $STR | grep -q NONE >/dev/null; then -# pr_svrty_best "not vulnerable (OK)" -# ret=$((ret + 0)) -# else -# pr_svrty_critical "VULNERABLE (NOT ok)" -# ret=$((ret + 1)) -# fi -# fi -# fi -# [[ $DEBUG -ge 2 ]] tmln_out "$STR" - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - - - -# As the name says. It expects as arg1 a GET command string. It returns 1 -# when GET command was stalled or killed (which is no not always used) -# and echos "warn_*". It return 0 when everything went ok and echos the -# compression if any. -sub_breach_helper() { - local get_command="$1" - local detected_compression="" - local -i was_killed=0 - - safe_echo "$get_command" | $OPENSSL s_client $(s_client_options "$OPTIMAL_PROTO $BUGS -quiet -ign_eof -connect $NODEIP:$PORT $PROXY $SNI") 1>$TMPFILE 2>$ERRFILE & - wait_kill $! $HEADER_MAXSLEEP - was_killed=$? # !=0 when it was killed - detected_compression=$(grep -ia ^Content-Encoding: $TMPFILE) - detected_compression="$(strip_lf "$detected_compression")" - detected_compression="${detected_compression#*:}" - detected_compression="$(strip_spaces "$detected_compression")" - if [[ ! -s $TMPFILE ]]; then - if [[ $was_killed -eq 0 ]]; then - echo "warn_stalled" - else - echo "warn_killed" - fi - return 1 - elif [[ -z $detected_compression ]]; then - echo "no_compression" - else - echo "$detected_compression" - fi - return 0 -} - - - -# BREACH is a HTTP-level compression & an attack which works against any cipher suite and is agnostic to the -# version of TLS/SSL, more: http://www.breachattack.com/ . External referrers are the important thing here! -# Mitigation: see https://community.qualys.com/message/20360 -# Any URL can be vulnerable. Here only the given URL is tested. See also $when_makesense -# -run_breach() { - local header - local -i ret=0 - local referer useragent - local url="$1" - local spaces=" " - local disclaimer="" - local when_makesense=" Can be ignored for static pages or if no secrets in the page" - local cve="CVE-2013-3587" - local cwe="CWE-310" - local hint="" c="" - local jsonID="BREACH" - local compressions="gzip deflate compress br" - local has_compression=() - local detected_compression="" - local get_command="" - - [[ $SERVICE != HTTP ]] && [[ "$CLIENT_AUTH" != required ]] && return 7 - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for BREACH (HTTP compression) vulnerability " && outln - pr_bold " BREACH"; out " ($cve) " - if [[ "$CLIENT_AUTH" == required ]]; then - prln_warning "client x509-based authentication prevents this from being tested" - fileout "$jsonID" "WARN" "client x509-based authentication prevents this from being tested" "$cve" "$cwe" - return 7 - fi - - [[ -z "$url" ]] && url="/" - disclaimer=" - only supplied \"$url\" tested" - - referer="https://google.com/" - [[ "$NODE" =~ google ]] && referer="https://yandex.ru/" # otherwise we have a false positive for google.com - useragent="$UA_STD" - $SNEAKY && useragent="$UA_SNEAKY" - - # Assemble the GET command with all available compressions and send them all, initially. - # If the result is negative: we can just tell the finding and return. If it's - # positive: We already have identified 1x compression - get_command="GET $url HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $useragent\r\nReferer: $referer\r\nConnection: Close\r\nAccept-encoding: ${compressions// /,}\r\nAccept: */*\r\n\r\n" - detected_compression=$(sub_breach_helper "$get_command") - case "$detected_compression" in - warn_stalled) - pr_warning "First request failed (HTTP header request stalled and was terminated)" - fileout "$jsonID" "WARN" "Test failed as first HTTP request stalled and was terminated" "$cve" "$cwe" - ret=1 - ;; - warn_failed) - pr_warning "First request failed (HTTP header request was empty)" - fileout "$jsonID" "WARN" "Test failed as first HTTP response was empty" "$cve" "$cwe" - ret=1 - ;; - no_compression) - pr_svrty_good "no gzip/deflate/compress/br HTTP compression (OK) " - outln "$disclaimer" - fileout "$jsonID" "OK" "not vulnerable, no gzip/deflate/compress/br HTTP compression $disclaimer" "$cve" "$cwe" - ret=0 - ;; - *) # Now assemble the remaining compressions in $compressions and loop through them - has_compression+=("$detected_compression:yes") - compressions="${compressions//$detected_compression/}" - for c in $compressions; do - get_command="GET $url HTTP/1.1\r\nHost: $NODE\r\nUser-Agent: $useragent\r\nReferer: $referer\r\nConnection: Close\r\nAccept-encoding: ${c}\r\nAccept: */*\r\n\r\n" - detected_compression=$(sub_breach_helper "$get_command") - if [[ $? -ne 0 ]]; then - # This failure unlikely here. The initial request must have succeeded and this one then - # failed but we'd rather treat this correctly (e.d. IDS which triggers later). Not also - # we exit on the first stalled request. So if the first one with all compressions failed, - # we don't get here. It seems very unlikely the first failed and subsequent will succeed. - has_compression+=("$c:$compressions") - elif [[ "$detected_compression" =~ no_compression ]]; then - has_compression+=("$c:no") - debugme echo "has_compression: $c: no" - elif [[ -n "$detected_compression" ]]; then - has_compression+=("$c:yes") - debugme echo "has_compression: $c: yes" - else - prln_fixme "strange reply around line $((LINENO)) from sub_breach_helper()" - fi - done - - # Final verdict (if not happened preemptively before). We reuse $detected_compression here - detected_compression="" - if [[ ${has_compression[@]} =~ warn ]]; then - # warn_empty / warn_stalled - if [[ ${has_compression[@]} =~ warn_empty ]]; then - pr_warning "At least 1/4 checks failed (HTTP header request was empty, debug: ${has_compression[@]}" - out ", debug: ${has_compression[@]})" - fileout "$jsonID" "WARN" "Test failed as HTTP response was empty, debug: ${has_compression[@]}" "$cve" "$cwe" - else # warn_stalled - pr_warning "At least 1/4 checks failed (HTTP header request stalled and was terminated" - out ", debug: ${has_compression[@]})" - fileout "$jsonID" "WARN" "Test failed as HTTP request stalled and was terminated" "$cve" "$cwe" - fi - else - for c in ${has_compression[@]}; do - if [[ $c =~ yes ]]; then - detected_compression+="${c%:*} " - fi - done - detected_compression="$(strip_trailing_space "$detected_compression")" - pr_svrty_medium "potentially NOT ok, \"$detected_compression\" HTTP compression detected." - outln "$disclaimer" - outln "${spaces}${when_makesense}" - fileout "$jsonID" "MEDIUM" "potentially VULNERABLE, $detected_compression HTTP compression detected $disclaimer" "$cve" "$cwe" "$hint" - fi - debugme outln "${spaces}has_compression: ${has_compression[@]}" - ;; - esac - - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - - -# SWEET32 (https://sweet32.info/). Birthday attacks on 64-bit block ciphers. -# In a nutshell: don't use 3DES ciphers anymore (DES, RC2 and IDEA too). -# Please note as opposed to RC4 (stream cipher) RC2 is a block cipher. -# -run_sweet32() { - local -i sclient_success=1 - local sweet32_ciphers="IDEA-CBC-SHA:IDEA-CBC-MD5:RC2-CBC-MD5:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:DES-CBC3-MD5:DES-CBC3-SHA:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:DES-CFB-M1:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:EXP1024-RC2-CBC-MD5:DES-CBC-MD5:DES-CBC-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" - local sweet32_ciphers_hex="00,07, 00,21, 00,25, c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,17, 00,1b, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, fe,ff, ff,e0, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,1a, 00,62, 00,09, 00,61, 00,1e, 00,22, fe,fe, ff,e1, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e" - local ssl2_sweet32_ciphers='RC2-CBC-MD5:EXP-RC2-CBC-MD5:IDEA-CBC-MD5:DES-CBC-MD5:DES-CBC-SHA:DES-CBC3-MD5:DES-CBC3-SHA:DES-CFB-M1' - local ssl2_sweet32_ciphers_hex='03,00,80, 04,00,80, 05,00,80, 06,00,40, 06,01,40, 07,00,C0, 07,01,C0, FF,80,00' - local nr_cipher_minimal=21 - local proto - local cve="CVE-2016-2183 CVE-2016-6329" - local cwe="CWE-327" - local hint="" - local -i nr_sweet32_ciphers=0 nr_supported_ciphers=0 nr_ssl2_sweet32_ciphers=0 nr_ssl2_supported_ciphers=0 - local ssl2_sweet=false - local using_sockets=true - local tls1_1_vulnerable=false - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for SWEET32 (Birthday Attacks on 64-bit Block Ciphers) " && outln - pr_bold " SWEET32"; out " (${cve// /, }) " - - if "$TLS13_ONLY"; then - # Unfortunately there's no restriction using TLS 1.2 with $sweet32_ciphers - pr_svrty_best "not vulnerable (OK)" - [[ $DEBUG -ge 1 ]] && out ", TLS 1.3 doesn't offer such ciphers" - outln - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - return 0 - fi - - "$SSL_NATIVE" && using_sockets=false - # The openssl binary distributed has almost everything we need (PSK, KRB5 ciphers and feff, ffe0 are typically missing). - # Measurements show that there's little impact whether we use sockets or TLS here, so the default is sockets here. - if "$using_sockets"; then - for proto in 03 02 01 00; do - [[ $(has_server_protocol "$proto") -eq 1 ]] && continue - tls_sockets "$proto" "${sweet32_ciphers_hex}, 00,ff" - sclient_success=$? - [[ $sclient_success -eq 2 ]] && sclient_success=0 - [[ $sclient_success -eq 0 ]] && break - done - if [[ 1 -ne $(has_server_protocol "ssl2") ]]; then - sslv2_sockets "$ssl2_sweet32_ciphers_hex" - case $? in - 3) ssl2_sweet=true - add_proto_offered ssl2 yes ;; - 0) ;; # ssl2_sweet=false - 1|4|6|7) debugme "${FUNCNAME[0]}: test problem we don't handle here" - ;; - esac - fi - else - nr_sweet32_ciphers=$(count_ciphers $sweet32_ciphers) - nr_supported_ciphers=$(count_ciphers $(actually_supported_osslciphers $sweet32_ciphers)) - debugme echo "$nr_sweet32_ciphers / $nr_supported_ciphers" - - nr_ssl2_sweet32_ciphers=$(count_ciphers $ssl2_sweet32_ciphers) - nr_ssl2_supported_ciphers=$(count_ciphers $(actually_supported_osslciphers $ssl2_sweet32_ciphers)) - debugme echo "$nr_ssl2_sweet32_ciphers / $nr_ssl2_supported_ciphers" - - if [[ $(( nr_supported_ciphers + nr_ssl2_supported_ciphers )) -le $nr_cipher_minimal ]]; then - pr_local_problem "Only ${nr_supported_ciphers}+${nr_ssl2_supported_ciphers} \"SWEET32 ciphers\" found in your $OPENSSL." - outln " Test skipped" - fileout "SWEET32" "WARN" "Not tested, lack of local support ($((nr_supported_ciphers + nr_ssl2_supported_ciphers)) ciphers only)" "$cve" "$cwe" "$hint" - return 1 - fi - for proto in -no_ssl2 -tls1_1 -tls1 -ssl3; do - [[ $nr_supported_ciphers -eq 0 ]] && break - ! "$HAS_SSL3" && [[ "$proto" == -ssl3 ]] && continue - if [[ "$proto" != -no_ssl2 ]]; then - "$FAST" && break - [[ $(has_server_protocol "${proto:1}") -eq 1 ]] && continue - fi - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS $proto -cipher $sweet32_ciphers -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" - - # tls_sockets() needs to parse the full response since the following code is - # looking for "BEGIN CERTIFICATE" when the TLS connection is successful. It - # may be possible to speed up this code by having the following code check - # the return value from tls_sockets() to determine whether the connection was - # successful rather than looking for "BEGIN CERTIFICATE". - case "$low_proto" in - "tls1_1") - tls_sockets "02" "56,00, $TLS_CIPHER" "all" "" "true" ;; - "tls1") - tls_sockets "01" "56,00, $TLS_CIPHER" "all" "" "true" ;; - "ssl3") - tls_sockets "00" "56,00, $TLS_CIPHER" "all" "" "true" ;; - esac - mv "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" "$TMPFILE" - DEBUG=$debug_level - fi - if grep -q "CONNECTED(00" "$TMPFILE"; then - if grep -qa 'BEGIN CERTIFICATE' "$TMPFILE"; then - if [[ -z "$POODLE" ]]; then - pr_warning "Rerun including POODLE SSL check. " - pr_svrty_medium "Downgrade attack prevention NOT supported" - fileout "$jsonID" "WARN" "NOT supported. Pls rerun with POODLE SSL check" - ret=1 - elif [[ "$POODLE" -eq 0 ]]; then - pr_svrty_high "Downgrade attack prevention NOT supported and vulnerable to POODLE SSL" - fileout "$jsonID" "HIGH" "NOT supported and vulnerable to POODLE SSL" - set_grade_cap "C" "Vulnerable to POODLE" - else - pr_svrty_medium "Downgrade attack prevention NOT supported" - fileout "$jsonID" "MEDIUM" "NOT supported" - fi - set_grade_cap "A" "Does not support TLS_FALLBACK_SCSV" - - elif grep -qa "alert inappropriate fallback" "$TMPFILE"; then - pr_svrty_good "Downgrade attack prevention supported (OK)" - fileout "$jsonID" "OK" "supported" - elif grep -qa "alert handshake failure" "$TMPFILE"; then - pr_svrty_good "Probably OK. " - fileout "$jsonID" "OK" "Probably oK" - # see RFC 7507, https://github.com/drwetter/testssl.sh/issues/121 - # other case reported by Nicolas was F5 and at costumer of mine: the same - pr_svrty_medium "But received non-RFC-compliant \"handshake failure\" instead of \"inappropriate fallback\"" - fileout "$jsonID" "MEDIUM" "received non-RFC-compliant \"handshake failure\" instead of \"inappropriate fallback\"" - elif grep -qa "ssl handshake failure" "$TMPFILE"; then - pr_svrty_medium "some unexpected \"handshake failure\" instead of \"inappropriate fallback\"" - fileout "$jsonID" "MEDIUM" "some unexpected \"handshake failure\" instead of \"inappropriate fallback\" (likely: warning)" - else - pr_warning "Check failed, unexpected result " - out ", run $PROG_NAME -Z --debug=1 and look at $TEMPDIR/*tls_fallback_scsv.txt" - fileout "$jsonID" "WARN" "Check failed, unexpected result, run $PROG_NAME -Z --debug=1 and look at $TEMPDIR/*tls_fallback_scsv.txt" - ret=1 - fi - else - pr_warning "test failed (couldn't connect)" - fileout "$jsonID" "WARN" "Check failed. (couldn't connect)" - ret=1 - fi - - outln - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - - -# Factoring RSA Export Keys: don't use EXPORT RSA ciphers, see https://freakattack.com/ -run_freak() { - local -i sclient_success=0 - local -i i nr_supported_ciphers=0 len - # with correct build it should list these 9 ciphers (plus the two latter as SSLv2 ciphers): - local exportrsa_cipher_list="EXP1024-DES-CBC-SHA:EXP1024-RC2-CBC-MD5:EXP1024-RC4-SHA:EXP1024-RC4-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5" - local exportrsa_tls_cipher_list_hex="00,62, 00,61, 00,64, 00,60, 00,14, 00,0E, 00,08, 00,06, 00,03" - local exportrsa_ssl2_cipher_list_hex="04,00,80, 02,00,80, 00,00,00" - local detected_ssl2_ciphers - local addtl_warning="" hexc - local using_sockets=true - local cve="CVE-2015-0204" - local cwe="CWE-310" - local hint="" - local jsonID="FREAK" - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for FREAK attack " && outln - pr_bold " FREAK"; out " ($cve) " - - if "$TLS13_ONLY"; then - pr_svrty_best "not vulnerable (OK)" - [[ $DEBUG -ge 1 ]] && out ", TLS 1.3 only server" - outln - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - return 0 - fi - - "$SSL_NATIVE" && using_sockets=false - if "$using_sockets"; then - nr_supported_ciphers=$(count_words "$exportrsa_tls_cipher_list_hex")+$(count_words "$exportrsa_ssl2_cipher_list_hex") - else - nr_supported_ciphers=$(count_ciphers $(actually_supported_osslciphers $exportrsa_cipher_list)) - fi - - case $nr_supported_ciphers in - 0) prln_local_problem "$OPENSSL doesn't have any EXPORT RSA ciphers configured" - fileout "$jsonID" "WARN" "Not tested. $OPENSSL doesn't have any EXPORT RSA ciphers configured" "$cve" "$cwe" - return 0 - ;; - 1|2|3) - addtl_warning=" ($magenta""tested only with $nr_supported_ciphers out of 9 ciphers only!$off)" ;; - 4|5|6|7) - addtl_warning=" (tested with $nr_supported_ciphers/9 ciphers)" ;; - 8|9|10|11) - addtl_warning="" ;; - esac - if "$using_sockets"; then - tls_sockets "03" "$exportrsa_tls_cipher_list_hex, 00,ff" - sclient_success=$? - [[ $sclient_success -eq 2 ]] && sclient_success=0 - - # TLS handshake failed with ciphers above. Now we check SSLv2 -- unless we know it's not available - if [[ $sclient_success -ne 0 ]] && [[ $(has_server_protocol ssl2) -ne 1 ]]; then - sslv2_sockets "$exportrsa_ssl2_cipher_list_hex" "true" - if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then - exportrsa_ssl2_cipher_list_hex="$(strip_spaces "${exportrsa_ssl2_cipher_list_hex//,/}")" - len=${#exportrsa_ssl2_cipher_list_hex} - detected_ssl2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" - for (( i=0; i$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TEMPDIR/dh_p.txt - if [[ ! -s "$common_primes_file" ]]; then - prln_local_problem "couldn't read common primes file $common_primes_file" - out "${spaces}" - fileout "$jsonID2" "WARN" "couldn't read common primes file $common_primes_file" - return 1 - else - dh_p="$(toupper "$dh_p")" - # In the previous line of the match is basically the hint we want to echo - # the most elegant thing to get the previous line [ awk '/regex/ { print x }; { x=$0 }' ] doesn't work with gawk - lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null | awk -F':' '{ print $1 }') - if [[ "$lineno_matched" -ne 0 ]]; then - DH_GROUP_OFFERED="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" - #subret=1 # vulnerable: common prime - else - DH_GROUP_OFFERED="Unknown DH group" - : - #subret=0 # not vulnerable: no known common prime - fi - return 0 - fi -} - - -# helper function for run_logjam see below -# -out_common_prime() { - local jsonID2="$1" - local cve="$2" - local cwe="$3" - - [[ "$DH_GROUP_OFFERED" == ffdhe* ]] && [[ ! "$DH_GROUP_OFFERED" =~ \ ]] && DH_GROUP_OFFERED="RFC7919/$DH_GROUP_OFFERED" - if [[ "$DH_GROUP_OFFERED" =~ ffdhe ]] && [[ "$DH_GROUP_OFFERED" =~ \ ]]; then - out "common primes detected: "; pr_italic "$DH_GROUP_OFFERED" - fileout "$jsonID2" "INFO" "$DH_GROUP_OFFERED" "$cve" "$cwe" - # Now (below) size matters -- i.e. the bit size. As this is about a known prime we label it more strict. - # This needs maybe needs another thought as it could appear inconsistent with run_fs and elsewhere. - # for now we label the bit size similar in the screen, but distinguish the leading text for logjam before - elif [[ $DH_GROUP_LEN_P -le 800 ]]; then - pr_svrty_critical "VULNERABLE (NOT ok):"; out " common prime: " - fileout "$jsonID2" "CRITICAL" "$DH_GROUP_OFFERED" "$cve" "$cwe" - pr_dh "$DH_GROUP_OFFERED" $DH_GROUP_LEN_P - elif [[ $DH_GROUP_LEN_P -le 1024 ]]; then - # really? Here we assume that 1024-bit common prime for nation states are worth and possible to precompute (TBC) - # otherwise 1024 are just medium - pr_svrty_high "VULNERABLE (NOT ok):"; out " common prime: " - fileout "$jsonID2" "HIGH" "$DH_GROUP_OFFERED" "$cve" "$cwe" - pr_dh "$DH_GROUP_OFFERED" $DH_GROUP_LEN_P - elif [[ $DH_GROUP_LEN_P -le 1536 ]]; then - pr_svrty_low "common prime: " - fileout "$jsonID2" "LOW" "$DH_GROUP_OFFERED" "$cve" "$cwe" - pr_dh "$DH_GROUP_OFFERED" $DH_GROUP_LEN_P - else - out "common prime with $DH_GROUP_LEN_P bits detected: " - fileout "$jsonID2" "INFO" "$DH_GROUP_OFFERED" "$cve" "$cwe" - pr_dh "$DH_GROUP_OFFERED" $DH_GROUP_LEN_P - fi -} - - -# see https://weakdh.org/logjam.html -run_logjam() { - local -i sclient_success=0 - local exportdh_cipher_list="EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA" - local exportdh_cipher_list_hex="00,63, 00,65, 00,14, 00,11" - local all_dh_ciphers="cc,15, 00,b3, 00,91, c0,97, 00,a3, 00,9f, cc,aa, c0,a3, c0,9f, 00,6b, 00,6a, 00,39, 00,38, 00,c4, 00,c3, 00,88, 00,87, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, 00,ab, cc,ad, c0,a7, c0,43, c0,45, c0,47, c0,53, c0,57, c0,5b, c0,67, c0,6d, c0,7d, c0,81, c0,85, c0,91, 00,a2, 00,9e, c0,a2, c0,9e, 00,aa, c0,a6, 00,67, 00,40, 00,33, 00,32, 00,be, 00,bd, 00,9a, 00,99, 00,45, 00,44, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, 00,b2, 00,90, c0,96, c0,42, c0,44, c0,46, c0,52, c0,56, c0,5a, c0,66, c0,6c, c0,7c, c0,80, c0,84, c0,90, 00,66, 00,18, 00,8e, 00,16, 00,13, 00,1b, 00,8f, 00,63, 00,15, 00,12, 00,1a, 00,65, 00,14, 00,11, 00,19, 00,17, 00,b5, 00,b4, 00,2d" # 93 ciphers - local -i i nr_supported_ciphers=0 server_key_exchange_len=0 ephemeral_pub_len=0 - local addtl_warning="" hexc - local -i ret=0 subret=0 - local server_key_exchange key_bitstring="" - local spaces=" " - local vuln_exportdh_ciphers=false - local openssl_no_expdhciphers=false - local str="" - local using_sockets=true - local cve="CVE-2015-4000" - local cwe="CWE-310" - local hint="" - local jsonID="LOGJAM" - local jsonID2="${jsonID}-common_primes" - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for LOGJAM vulnerability " && outln - pr_bold " LOGJAM"; out " ($cve), experimental " - - "$SSL_NATIVE" && using_sockets=false - # Also as the openssl binary distributed has everything we need measurements show that - # there's no impact whether we use sockets or TLS here, so the default is sockets here - if ! "$using_sockets"; then - nr_supported_ciphers=$(count_ciphers $(actually_supported_osslciphers $exportdh_cipher_list)) - debugme echo $nr_supported_ciphers - case $nr_supported_ciphers in - 0) prln_local_problem "$OPENSSL doesn't have any DH EXPORT ciphers configured" - fileout "$jsonID" "WARN" "Not tested. $OPENSSL doesn't support any DH EXPORT ciphers" "$cve" "$cwe" - out "$spaces" - openssl_no_expdhciphers=true - ;; - 1|2|3) addtl_warning=" ($magenta""tested w/ $nr_supported_ciphers/4 ciphers only!$off)" ;; - 4) ;; - esac - fi - - # test for DH export ciphers first - if "$using_sockets"; then - tls_sockets "03" "$exportdh_cipher_list_hex, 00,ff" - sclient_success=$? - [[ $sclient_success -eq 2 ]] && sclient_success=0 - [[ $sclient_success -eq 0 ]] && vuln_exportdh_ciphers=true - elif [[ $nr_supported_ciphers -ne 0 ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -cipher $exportdh_cipher_list -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE we should treat that some place else before - fi - if [[ "$DH_GROUP_OFFERED" =~ Unknown ]]; then - subret=0 # no common DH key detected - else - subret=1 # known prime/DH key - fi - elif [[ -z "$DH_GROUP_OFFERED" ]]; then - subret=3 - fi - - # Now if we have DH export ciphers we print them out first - if "$vuln_exportdh_ciphers"; then - pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DH EXPORT ciphers" - fileout "$jsonID" "HIGH" "VULNERABLE, uses DH EXPORT ciphers" "$cve" "$cwe" "$hint" - if [[ $subret -eq 3 ]]; then - out ", no DH key detected with <= TLS 1.2" - fileout "$jsonID2" "OK" "no DH key detected with <= TLS 1.2" - elif [[ $subret -eq 1 ]]; then - out "\n${spaces}" - out_common_prime "$jsonID2" "$cve" "$cwe" - elif [[ $subret -eq 0 ]]; then - out " no common primes detected" - fileout "$jsonID2" "INFO" "--" "$cve" "$cwe" - elif [[ $ret -eq 1 ]]; then - out "FIXME 1" - fi - else - if [[ $subret -eq 1 ]]; then - out_common_prime "$jsonID2" "$cve" "$cwe" - if ! "$openssl_no_expdhciphers"; then - outln "," - out "${spaces}but no DH EXPORT ciphers${addtl_warning}" - fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" - fi - elif [[ $subret -eq 3 ]]; then - pr_svrty_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${addtl_warning}" - fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" - out ", no DH key detected with <= TLS 1.2" - fileout "$jsonID2" "OK" "no DH key with <= TLS 1.2" "$cve" "$cwe" - elif [[ $subret -eq 0 ]]; then - pr_svrty_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${addtl_warning}" - fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" - # we issue a special warning if there's no common prime but the bit length is too low - if [[ $DH_GROUP_LEN_P -le 1024 ]]; then - out "\n${spaces}But: " - pr_dh "$DH_GROUP_OFFERED" $DH_GROUP_LEN_P - case $? in - 1) fileout "$jsonID" "CRITICAL" "no DH EXPORT ciphers, no common prime but $DH_GROUP_OFFERED has only $DH_GROUP_LEN_P bits, $addtl_warning" "$cve" "$cwe" ;; - 2) fileout "$jsonID" "HIGH" "no DH EXPORT ciphers, no common prime but $DH_GROUP_OFFERED has only $DH_GROUP_LEN_P bits, $addtl_warning" "$cve" "$cwe";; - 3) fileout "$jsonID" "MEDIUM" "no DH EXPORT ciphers, no common prime but $DH_GROUP_OFFERED has only $DH_GROUP_LEN_P bits, $addtl_warning" "$cve" "$cwe";; - esac - else - out ", no common prime detected" - fileout "$jsonID2" "OK" "--" "$cve" "$cwe" - fi - elif [[ $ret -eq 1 ]]; then - pr_svrty_good "partly not vulnerable:"; out " no DH EXPORT ciphers${addtl_warning}" - fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" - fi - fi - - [[ $DH_GROUP_LEN_P -gt 0 ]] && set_key_str_score "DHE" $DH_GROUP_LEN_P - - outln - tmpfile_handle ${FUNCNAME[0]}.txt - return $ret -} - -# Decrypting RSA with Obsolete and Weakened eNcryption, more @ https://drownattack.com/ -run_drown() { - local -i nr_ciphers_detected ret=0 - local spaces=" " - local cert_fingerprint_sha2="" - local cve="CVE-2016-0800 CVE-2016-0703" - local cwe="CWE-310" - local hint="" - local jsonID="DROWN" - local censys_host_url="https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE" - - if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then - outln - pr_headlineln " Testing for DROWN vulnerability " - outln - fi -# if we want to use OPENSSL: check for < openssl 1.0.2g, openssl 1.0.1s if native openssl - pr_bold " DROWN"; out " (${cve// /, }) " - - # Any fingerprint that is placed in $RSA_CERT_FINGERPRINT_SHA2 is also added to - # to $CERT_FINGERPRINT_SHA2, so if $CERT_FINGERPRINT_SHA2 is not empty, but - # $RSA_CERT_FINGERPRINT_SHA2 is empty, then the server doesn't have an RSA certificate. - if [[ -z "$CERT_FINGERPRINT_SHA2" ]]; then - get_host_cert "-cipher aRSA -no_ssl2" - [[ $? -eq 0 ]] && cert_fingerprint_sha2="$($OPENSSL x509 -noout -in $HOSTCERT -fingerprint -sha256 2>>$ERRFILE | sed -e 's/^.*Fingerprint=//' -e 's/://g' )" - else - cert_fingerprint_sha2="$RSA_CERT_FINGERPRINT_SHA2" - cert_fingerprint_sha2=${cert_fingerprint_sha2/SHA256 /} - fi - - if [[ "$STARTTLS_PROTOCOL" =~ irc ]]; then - prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" - return 1 - fi - - censys_host_url="$censys_host_url&q=$cert_fingerprint_sha2" - if [[ $(has_server_protocol ssl2) -ne 1 ]]; then - sslv2_sockets - else - [[ aaa == bbb ]] # provoke return code=1 - fi - - case $? in - 7) # strange reply, couldn't convert the cipher spec length to a hex number - pr_fixme "strange v2 reply " - outln " (rerun with DEBUG >=2)" - [[ $DEBUG -ge 3 ]] && hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" | head -1 - fileout "$jsonID" "WARN" "received a strange SSLv2 reply (rerun with DEBUG>=2)" "$cve" "$cwe" - ret=1 - ;; - 3) # vulnerable, [[ -n "$cert_fingerprint_sha2" ]] test is not needed as we should have RSA certificate here - lines=$(count_lines "$(hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" 2>/dev/null)") - debugme tm_out " ($lines lines) " - add_proto_offered ssl2 yes - if [[ "$lines" -gt 1 ]]; then - nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) - if [[ 0 -eq "$nr_ciphers_detected" ]]; then - prln_svrty_high "CVE-2015-3197: SSLv2 supported but couldn't detect a cipher (NOT ok)"; - fileout "$jsonID" "HIGH" "SSLv2 offered, but could not detect a cipher. Make sure you don't use this certificate elsewhere, see $censys_host_url" "$cve CVE-2015-3197" "$cwe" "$hint" - else - prln_svrty_critical "VULNERABLE (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers"; - fileout "$jsonID" "CRITICAL" "VULNERABLE, SSLv2 offered with $nr_ciphers_detected ciphers. Make sure you don't use this certificate elsewhere, see $censys_host_url" "$cve" "$cwe" "$hint" - set_grade_cap "F" "Vulnerable to DROWN" - fi - outln "$spaces Make sure you don't use this certificate elsewhere, see:" - out "$spaces " - pr_url "$censys_host_url" - outln - fi - ;; - *) prln_svrty_best "not vulnerable on this host and port (OK)" - fileout "$jsonID" "OK" "not vulnerable on this host and port" "$cve" "$cwe" - if [[ -n "$cert_fingerprint_sha2" ]]; then - outln "$spaces make sure you don't use this certificate elsewhere with SSLv2 enabled services, see" - out "$spaces " - pr_url "$censys_host_url" - outln - fileout "${jsonID}_hint" "INFO" "Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see $censys_host_url" "$cve" "$cwe" - else - outln "$spaces no RSA certificate, thus certificate can't be used with SSLv2 elsewhere" - fileout "${jsonID}_hint" "INFO" "no RSA certificate, can't be used with SSLv2 elsewhere" "$cve" "$cwe" - fi - ;; - esac - - return $ret -} - - - -# Browser Exploit Against SSL/TLS: don't use CBC Ciphers in SSLv3 TLSv1.0 -run_beast(){ - local hexc dash cbc_cipher sslvers auth mac - local -a ciph hexcode normalized_hexcode kx enc export2 - local proto proto_hex - local -i i subret nr_ciphers=0 sclient_success=0 - local detected_cbc_ciphers="" ciphers_to_test - local higher_proto_supported="" - local vuln_beast=false - local spaces=" " - local cr=$'\n' - local first=true - local continued=false - local cbc_cipher_list="EXP-RC2-CBC-MD5:IDEA-CBC-SHA:EXP-DES-CBC-SHA:DES-CBC-SHA:DES-CBC3-SHA:EXP-DH-DSS-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:DH-DSS-DES-CBC3-SHA:EXP-DH-RSA-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-RSA-DES-CBC3-SHA:EXP-EDH-DSS-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:EDH-DSS-DES-CBC3-SHA:EXP-EDH-RSA-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EXP-ADH-DES-CBC-SHA:ADH-DES-CBC-SHA:ADH-DES-CBC3-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-IDEA-CBC-SHA:KRB5-DES-CBC-MD5:KRB5-DES-CBC3-MD5:KRB5-IDEA-CBC-MD5:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-MD5:EXP-KRB5-RC2-CBC-MD5:AES128-SHA:DH-DSS-AES128-SHA:DH-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:ADH-AES128-SHA:AES256-SHA:DH-DSS-AES256-SHA:DH-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ADH-AES256-SHA:CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DHE-RSA-CAMELLIA128-SHA:ADH-CAMELLIA128-SHA:EXP1024-RC2-CBC-MD5:EXP1024-DES-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DHE-RSA-CAMELLIA256-SHA:ADH-CAMELLIA256-SHA:PSK-3DES-EDE-CBC-SHA:PSK-AES128-CBC-SHA:PSK-AES256-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-AES128-CBC-SHA:DHE-PSK-AES256-CBC-SHA:RSA-PSK-3DES-EDE-CBC-SHA:RSA-PSK-AES128-CBC-SHA:RSA-PSK-AES256-CBC-SHA:SEED-SHA:DH-DSS-SEED-SHA:DH-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-SEED-SHA:ADH-SEED-SHA:PSK-AES128-CBC-SHA256:PSK-AES256-CBC-SHA384:DHE-PSK-AES128-CBC-SHA256:DHE-PSK-AES256-CBC-SHA384:RSA-PSK-AES128-CBC-SHA256:RSA-PSK-AES256-CBC-SHA384:ECDH-ECDSA-DES-CBC3-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AECDH-DES-CBC3-SHA:AECDH-AES128-SHA:AECDH-AES256-SHA:SRP-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-DSS-AES-256-CBC-SHA:ECDHE-PSK-3DES-EDE-CBC-SHA:ECDHE-PSK-AES128-CBC-SHA:ECDHE-PSK-AES256-CBC-SHA:ECDHE-PSK-AES128-CBC-SHA256:ECDHE-PSK-AES256-CBC-SHA384:PSK-CAMELLIA128-SHA256:PSK-CAMELLIA256-SHA384:DHE-PSK-CAMELLIA128-SHA256:DHE-PSK-CAMELLIA256-SHA384:RSA-PSK-CAMELLIA128-SHA256:RSA-PSK-CAMELLIA256-SHA384:ECDHE-PSK-CAMELLIA128-SHA256:ECDHE-PSK-CAMELLIA256-SHA384" - local cbc_ciphers_hex="00,06, 00,07, 00,08, 00,09, 00,0A, 00,0B, 00,0C, 00,0D, 00,0E, 00,0F, 00,10, 00,11, 00,12, 00,13, 00,14, 00,15, 00,16, 00,19, 00,1A, 00,1B, 00,1E, 00,1F, 00,21, 00,22, 00,23, 00,25, 00,26, 00,27, 00,29, 00,2A, 00,2F, 00,30, 00,31, 00,32, 00,33, 00,34, 00,35, 00,36, 00,37, 00,38, 00,39, 00,3A, 00,41, 00,42, 00,43, 00,44, 00,45, 00,46, 00,61, 00,62, 00,63, 00,84, 00,85, 00,86, 00,87, 00,88, 00,89, 00,8B, 00,8C, 00,8D, 00,8F, 00,90, 00,91, 00,93, 00,94, 00,95, 00,96, 00,97, 00,98, 00,99, 00,9A, 00,9B, 00,AE, 00,AF, 00,B2, 00,B3, 00,B6, 00,B7, C0,03, C0,04, C0,05, C0,08, C0,09, C0,0A, C0,0D, C0,0E, C0,0F, C0,12, C0,13, C0,14, C0,17, C0,18, C0,19, C0,1A, C0,1B, C0,1C, C0,1D, C0,1E, C0,1F, C0,21, C0,22, C0,34, C0,35, C0,36, C0,37, C0,38, C0,64, C0,65, C0,66, C0,67, C0,68, C0,69, C0,70, C0,71, C0,94, C0,95, C0,96, C0,97, C0,98, C0,99, C0,9A, C0,9B, FE,FE, FE,FF, FF,E0, FF,E1" - local has_dh_bits="$HAS_DH_BITS" - local using_sockets=true - local cve="CVE-2011-3389" - local cwe="CWE-20" - local hint="" - local jsonID="BEAST" - - if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then - outln - pr_headlineln " Testing for BEAST vulnerability " - outln - fi - pr_bold " BEAST"; out " ($cve) " - - if "$TLS13_ONLY" || [[ $(has_server_protocol ssl3) -eq 1 && $(has_server_protocol tls1) -eq 1 ]]; then - pr_svrty_good "not vulnerable (OK)" - outln ", no SSL3 or TLS1" - fileout "$jsonID" "OK" "not vulnerable, no SSL3 or TLS1" "$cve" "$cwe" - return 0 - fi - - "$SSL_NATIVE" && using_sockets=false - # $cbc_ciphers_hex has 126 ciphers, we omitted SRP-AES-256-CBC-SHA bc the trailing 00,ff below will pose - # a problem for ACE loadbalancers otherwise. So in case we know this is not true, we'll re-add it - ! "$SERVER_SIZE_LIMIT_BUG" && "$using_sockets" && cbc_ciphers_hex="$cbc_ciphers_hex, C0,20" - - [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false - if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - hexc="${TLS_CIPHER_HEXCODE[i]}" - if [[ ${#hexc} -eq 9 ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CBC ]] && \ - [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA256 ]] && [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA384 ]]; then - ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" - hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" - rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" - kx[nr_ciphers]="${TLS_CIPHER_KX[i]}" - enc[nr_ciphers]="${TLS_CIPHER_ENC[i]}" - export2[nr_ciphers]="${TLS_CIPHER_EXPORT[i]}" - ossl_supported[nr_ciphers]=${TLS_CIPHER_OSSL_SUPPORTED[i]} - if "$using_sockets" && "$WIDE" && ! "$has_dh_bits" && \ - [[ ${kx[nr_ciphers]} == Kx=ECDH || ${kx[nr_ciphers]} == Kx=DH || ${kx[nr_ciphers]} == Kx=EDH ]]; then - ossl_supported[nr_ciphers]=false - fi - if [[ "${hexc:2:2}" == 00 ]]; then - normalized_hexcode[nr_ciphers]="x${hexc:7:2}" - else - normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" - fi - nr_ciphers+=1 - fi - done - else - # no sockets, openssl - while read hexc dash ciph[nr_ciphers] sslvers kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do - if [[ ":${cbc_cipher_list}:" =~ :${ciph[nr_ciphers]}: ]]; then - ossl_supported[nr_ciphers]=true - if [[ "${hexc:2:2}" == "00" ]]; then - normalized_hexcode[nr_ciphers]="x${hexc:7:2}" - else - normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" - fi - nr_ciphers+=1 - fi - done < <(actually_supported_osslciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 'ALL' "-tls1 -V") - fi - - # first determine whether it's mitigated by higher protocols - for proto in tls1_1 tls1_2; do - subret=$(has_server_protocol "$proto") - if [[ $subret -eq 0 ]]; then - case $proto in - tls1_1) higher_proto_supported+=" TLSv1.1" ;; - tls1_2) higher_proto_supported+=" TLSv1.2" ;; - esac - elif [[ $subret -eq 2 ]]; then - $OPENSSL s_client $(s_client_options "-state -"${proto}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") 2>>$ERRFILE >$TMPFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE 1.0 - pr_svrty_low "VULNERABLE" - outln " -- but also supports higher protocols (possible mitigation) $higher_proto_supported" - outln - else - out "$spaces" - pr_svrty_low "VULNERABLE" - outln " -- but also supports higher protocols $higher_proto_supported (likely mitigated)" - fi - fileout "$jsonID" "LOW" "VULNERABLE -- but also supports higher protocols $higher_proto_supported (likely mitigated)" "$cve" "$cwe" "$hint" - else - if "$WIDE"; then - outln - else - out "$spaces" - fi - pr_svrty_medium "VULNERABLE" - outln " -- and no higher protocols as mitigation supported" - fileout "$jsonID" "MEDIUM" "VULNERABLE -- and no higher protocols as mitigation supported" "$cve" "$cwe" "$hint" - set_grade_cap "B" "Vulnerable to BEAST" - fi - fi - "$first" && ! "$vuln_beast" && prln_svrty_good "no CBC ciphers found for any protocol (OK)" - - "$using_sockets" && HAS_DH_BITS="$has_dh_bits" - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - -# This is a quick test for Winshock, MS14-066, a vulnerability in the TLS stack of Microsoft which leads to RCE. -# This vulnerability affected all SChannel services -- most notably RDP (port 3398 normally). See -# https://support.microsoft.com/en-us/help/2992611/ms14-066-vulnerability-in-schannel-could-allow-remote-code-execution-n -# and http://www.securitysift.com/exploiting-ms14-066-cve-2014-6321-aka-winshock for "exploiting"/crashing lsass.exe. -# What we do here is giving a strong hint. -# -# First we check whether TLS 1.3 is available. Then with the fix MS introduced came additional ciphers -# TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_256_GCM_SHA384 TLS_RSA_WITH_AES_128_GCM_SHA256 -# = DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-GCM-SHA256. -# We also check for the absence of ciphers which came in way later (ECDHE-RSA-AES128-GCM-SHA256 / ECDHE-RSA-AES256-GCM-SHA384), or -# more ciphers like ARIA, CCM, CAMELLIA and CHACHAPOLY. (Those ciphers could also be retrieved from our array TLS_CIPHER_RFC_NAME[i] -# and using TLS_CIPHER_HEXCODE[i]. We may want to # do that later. We check for all this in sockets only to avoid overhead.) -# Then we check for absence of elliptical curves and TLS extensions. -# That all should minimize false # positives because of middle boxes, proxies and later Windows versions. -# The last straw then is to check for webserver banners (http.sys, IIS/8.0 and IIS/8.5). -# -run_winshock() { - local wsfixed_ciphers='00,9F, 00,9D, 00,9E, 00,9C' - local aria_ciphers='C0,3D,C0,3F,C0,41,C0,43,C0,45,C0,47,C0,49,C0,4B,C0,4D,C0,4F,C0,51,C0,53,C0,55,C0,57,C0,59,C0,5B,C0,5D,C0,5F,C0,61,C0,63,C0,65,C0,67,C0,69,C0,6B,C0,6D,C0,6F,C0,71,C0,3C,C0,3E,C0,40,C0,42,C0,44,C0,46,C0,48,C0,4A,C0,4C,C0,4E,C0,50,C0,52,C0,54,C0,56,C0,58,C0,5A,C0,5C,C0,5E,C0,60,C0,62,C0,64,C0,66,C0,68,C0,6A,C0,6C,C0,6E,C0,70' - local camellia_ciphers='C0,9B,C0,99,C0,97,C0,95,C0,77,C0,73,00,C4,00,C3,00,C2,00,C1,00,88,00,87,00,86,00,85,00,C5,00,89,C0,79,C0,75,00,C0,00,84,C0,7B,C0,7D,C0,7F,C0,81,C0,83,C0,85,C0,87,C0,89,C0,8B,C0,8D,C0,8F,C0,91,C0,93,C0,76,C0,72,00,BE,00,BD,00,BC,00,BB,00,45,00,44,00,43,00,42,00,BF,00,46,C0,78,C0,74,00,BA,00,41,C0,9A,C0,98,C0,96,C0,94,C0,7A,C0,7C,C0,7E,C0,80,C0,82,C0,84,C0,86,C0,88,C0,8A,C0,8C,C0,8E,C0,90,C0,92' - local chacha_ccm_ciphers='CC,14,CC,13,CC,15,CC,A9,CC,A8,CC,AA,C0,AF,C0,AD,C0,A3,C0,9F,CC,AE,CC,AD,CC,AC,C0,AB,C0,A7,C0,A1,C0,9D,CC,AB,C0,A9,C0,A5,16,B7,16,B8,13,04,13,05,C0,AE,C0,AC,C0,A2,C0,9E,C0,AA,C0,A6,C0,A0,C0,9C,C0,A8,C0,A4' - # TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 / TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = ECDHE-RSA-AES128-GCM-SHA256 / ECDHE-RSA-AES256-GCM-SHA384 - # came in Server 2016, see https://notsomany.com/2016/08/26/achieve-a-on-sslabs-iis-8-5-windows-2012-r2/ - # https://docs.microsoft.com/en-us/windows/win32/secauthn/cipher-suites-in-schannel - local more_excluded_ciphers='C0,2F, C0,30' - # These are the three NIST curves allowed only. Keep in mind prime256v1=secp256r1 and MS labels them as P256, P384 and P521 - local allowed_curves="prime256v1 secp384r1 secp521r1" - local curve="" tls_ext="" - local -i sclient_success=0 - local server_banner="" - local check_patches=" - check patches locally to confirm" - local cve="CVE-2014-6321" - local cwe="CWE-94" - local jsonID="winshock" - - if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then - outln - pr_headlineln " Testing for winshock vulnerability " - outln - fi - pr_bold " Winshock"; out " ($cve), experimental " - - if [[ "$(has_server_protocol "tls1_3")" -eq 0 ]] ; then - # There's no MS server supporting TLS 1.3. Winshock was way back in time - pr_svrty_best "not vulnerable (OK)" - debugme echo " - TLS 1.3 found" - fileout "$jsonID" "OK" "not vulnerable " "$cve" "$cwe" - outln - return 0 - fi - if [[ "$STARTTLS_PROTOCOL" =~ irc ]]; then - prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" - return 1 - fi - - # Now we check whether any CAMELLIA, ARIA, CCM or CHACHA cipher is available. - # We do this in two shots in order to stay below the 128 cipher limit - tls_sockets "03" "${aria_ciphers},${chacha_ccm_ciphers}, 00,ff" - sclient_success=$? - if [[ $sclient_success -eq 0 ]] || [[ "$sclient_success" -eq 2 ]]; then - pr_svrty_best "not vulnerable (OK)" ; outln " - ARIA, CHACHA or CCM ciphers found" - fileout "$jsonID" "OK" "not vulnerable " "$cve" "$cwe" - return 0 - fi - tls_sockets "03" "${camellia_ciphers},${more_excluded_ciphers}, 00,ff" - sclient_success=$? - if [[ $sclient_success -eq 0 ]] || [[ "$sclient_success" -eq 2 ]]; then - pr_svrty_best "not vulnerable (OK)"; outln " - CAMELLIA or ECDHE_RSA GCM ciphers found" - fileout "$jsonID" "OK" "not vulnerable " "$cve" "$cwe" - return 0 - fi - - # Now we need to check the fixed ciphers - tls_sockets "03" "${wsfixed_ciphers}, 00,ff" - sclient_success=$? - if [[ $sclient_success -eq 0 ]] || [[ "$sclient_success" -eq 2 ]]; then - # has rollup ciphers - pr_svrty_best "not vulnerable (OK)"; outln " - GCM rollup ciphers found" - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - return 0 - elif [[ $sclient_success -ne 1 ]]; then - prln_warning "check failed, connect problem" - fileout "$jsonID" "WARN" "check failed, connect problem" "$cve" "$cwe" - return 1 - fi - - # Basic idea: https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations#Supported_elliptic_curves - # [[ -z "$CURVES_OFFERED" ]] && sub_check_curves - if [[ -n "$CURVES_OFFERED" ]]; then - # Check whether there are any additional curves besides $allowed_curves - for curve in $CURVES_OFFERED; do - if ! [[ $allowed_curves =~ $curve ]]; then - pr_svrty_best "not vulnerable (OK)"; outln " - curve $curve detected" - fileout "$jsonID" "OK" "not vulnerable - curve $curve detected" "$cve" "$cwe" - return 0 - fi - done - fi - #FIXME: The catch is that when a user didn't invoke run_fs() before, this wasn't processed + CURVES_OFFERED - # is empty. So we could call it like above but need to move curves detection into a separate function - # (~ sub_check_curves) which is some work. But also for the sake of clean code this needs to be done. - - - [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions - # Basis of the following https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations#Extensions - # Our standard: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml - - # According to Wikipedia above these are the ones which can be detected unders version of Windows - # Secure Renegotiation, Server Name Indication, Certificate Status Request, Supplemental Data, Extended Master Secret, ALPN - # supplemental_data(23) (RFC 4680) seems to have been overwritten by extended master secret(23) RFC 7627 - # local -a allowed_tls_ext=("server name" "status_request" "extended master secret" "application layer protocol negotiation") - # Instead we rather focus on the ones which according to that source weren't available - # Encrypt-then-MAC, Maximum Fragment Length, Keying Material Exporter, TLS Fallback SCSV, ClientHello Padding - # Padding is client side. Don't know what they mean by the fallback SCSV. That is not an extension - local -a forbidden_tls_ext=("encrypt-then-mac" "max fragment length") - # Open whether ec_point_formats, supported_groups(=elliptic_curves), heartbeat are supported under windows <=2012 - # key_share and supported_versions are extensions which came with TLS 1.3. We checked the protocol before. - if [[ -n "$TLS_EXTENSIONS" ]]; then - # Check whether there are any TLS extension which should not be available under <= Windows 2012 R2 - for tls_ext in $TLS_EXTENSIONS; do - # We use the whole array, got to be careful when the array becomes bigger (unintended match) - if [[ ${forbidden_tls_ext[@]} =~ $tls_ext ]]; then - pr_svrty_best "not vulnerable (OK)"; outln " - TLS extension $tls_ext detected" - fileout "$jsonID" "OK" "not vulnerable - TLS extension $tls_ext detected" "$cve" "$cwe" - return 0 - fi - done - fi - - # More would be possible if we look @ the following: - # See also https://github.com/cisco/joy/blob/master/fingerprinting/resources/fingerprint_db.json.gz - # https://resources.sei.cmu.edu/asset_files/Presentation/2019_017_001_539902.pdf - # https://raw.githubusercontent.com/cisco/joy/master/doc/using-joy-fingerprinting-00.pdf - - - - # Now the solid determination more or less done. What's left now is to detect the service - # and perform an educated guess. - - # Next we weed out is whether we run HTTP or RDP (on standard port). - # Using the experimental flag we can test it also on other ports / services - if [[ $SERVICE != HTTP ]] && [[ $PORT != 3389 ]] && ! "$EXPERIMENTAL"; then - pr_svrty_best "not vulnerable (OK)"; outln " - no HTTP or RDP" - fileout "$jsonID" "OK" "not vulnerable - no HTTP or RDP" "$cve" "$cwe" - return 0 - fi - - if [[ $SERVICE != HTTP ]] && [[ $PORT == 3389 ]]; then - # We take a security guess here (better safe than sorry) for RDP as we don't have a banner - out "probably "; pr_svrty_critical "vulnerable (NOT ok)"; outln "$check_patches" - fileout "${jsonID}" "CRITICAL" "probably vulnerable (NOT OK) $check_patches" - return 0 - fi - - # Now we have potentially vulnerable HTTP servers left where we grab the server banner. - # First choice for that is the HTTP header # file which we retrieved in a default run. - # From the service detection we also should have a header though as a fall back. - if [[ -s $HEADERFILE ]]; then - server_banner="$(grep -Eai '^Server:' $HEADERFILE)" - elif [[ -s "$TEMPDIR/$NODEIP.service_detection.txt" ]]; then - server_banner="$(grep -Eai '^Server:' "$TEMPDIR/$NODEIP.service_detection.txt")" - elif "$EXPERIMENTAL"; then - # If testing e.g. an SMTP server - : - else - # We can't use run_http_header here as it messes up the screen. We could automatically - # run it when --winshock is requested though but this should suffice here. - prln_warning "check failed, rerun with cmd line option --header " - fileout "$jsonID" "WARN" "check failed, connect problem" "$cve" "$cwe" - return 1 - fi - if [[ $server_banner =~ Microsoft-IIS\/8.5 ]]; then - # Windows 2012 R2 is less likely than Windows 2012 - out "probably "; pr_svrty_critical "vulnerable (NOT ok)"; outln "$check_patches" - fileout "${jsonID}" "CRITICAL" "probably vulnerable (NOT OK) $check_patches" - elif [[ $server_banner =~ Microsoft-IIS\/8.0 ]]; then - out "likely "; pr_svrty_critical "VULNERABLE (NOT ok)"; outln "$check_patches" - fileout "${jsonID}" "CRITICAL" "likely vulnerable (NOT OK) $check_patches" - elif [[ $server_banner =~ Microsoft-HTTPAPI\/2.0 ]]; then - # This is http.sys. It may or may not indicate a 2012 server. IIS is not yet configured though. - # So we have a peek on port 80 - http_get $NODE "$TEMPDIR/$NODE.$NODEIP.http-header.txt" - server_banner="$(grep -Eai '^Server:' $TEMPDIR/$NODE.$NODEIP.http-header.txt)" - if [[ $server_banner =~ Microsoft-IIS\/8.5 ]]; then - out "probably "; pr_svrty_critical "vulnerable (NOT ok)"; outln "$check_patches" - fileout "${jsonID}" "CRITICAL" "probably vulnerable (NOT OK) $check_patches" - elif [[ $server_banner =~ Microsoft-IIS\/8.0 ]]; then - out "likely "; pr_svrty_critical "VULNERABLE (NOT ok)"; outln "$check_patches" - fileout "${jsonID}" "CRITICAL" "likely vulnerable (NOT OK) $check_patches" - else - out "likely "; prln_svrty_best "not vulnerable (OK)" - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - outln - fi - elif "$EXPERIMENTAL"; then - out "seems "; pr_svrty_critical "vulnerable (NOT ok)"; outln "$check_patches" - fileout "${jsonID}" "CRITICAL" "seems vulnerable (NOT OK) $check_patches" - else - pr_svrty_best "not vulnerable (OK)" - outln " - doesn't seem to be IIS 8.x" - fileout "$jsonID" "OK" "not vulnerable - doesn't seem to be IIS 8.x" "$cve" "$cwe" - fi - return 0 -} - - -# https://web.archive.org/web/20200324101422/http://www.isg.rhul.ac.uk/tls/Lucky13.html -# Paper: https://doi.org/10.1109/SP.2013.42 -# in a nutshell: don't offer CBC suites (again). MAC as a fix for padding oracles is not enough. Best: TLS v1.2+ AES GCM -run_lucky13() { - local spaces=" " - local cbc_ciphers="ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:RSA-PSK-AES256-CBC-SHA384:DHE-PSK-AES256-CBC-SHA384:DHE-PSK-AES256-CBC-SHA:ECDHE-PSK-CAMELLIA256-SHA384:RSA-PSK-CAMELLIA256-SHA384:DHE-PSK-CAMELLIA256-SHA384:PSK-AES256-CBC-SHA384:PSK-CAMELLIA256-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CAMELLIA256-SHA384:DHE-RSA-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA256:DH-RSA-CAMELLIA256-SHA256:DH-DSS-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA256:ADH-AES256-SHA:ADH-CAMELLIA256-SHA256:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-CAMELLIA256-SHA384:ECDH-ECDSA-CAMELLIA256-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:ECDHE-PSK-AES256-CBC-SHA384:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA256:DH-RSA-CAMELLIA128-SHA256:DH-DSS-CAMELLIA128-SHA256:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA256:ADH-AES128-SHA:ADH-CAMELLIA128-SHA256:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-CAMELLIA128-SHA256:ECDH-ECDSA-CAMELLIA128-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:ECDHE-PSK-AES128-CBC-SHA256:ECDHE-PSK-AES128-CBC-SHA:RSA-PSK-AES128-CBC-SHA256:DHE-PSK-AES128-CBC-SHA256:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:ECDHE-PSK-CAMELLIA128-SHA256:RSA-PSK-CAMELLIA128-SHA256:DHE-PSK-CAMELLIA128-SHA256:PSK-AES128-CBC-SHA256:PSK-CAMELLIA128-SHA256:IDEA-CBC-SHA:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" - cbc_ciphers_hex1="c0,28, c0,24, c0,14, c0,0a, c0,22, c0,21, c0,20, 00,b7, 00,b3, 00,91, c0,9b, c0,99, c0,97, 00,af, c0,95, 00,6b, 00,6a, 00,69, 00,68, 00,39, 00,38, 00,37, 00,36, c0,77, c0,73, 00,c4, 00,c3, 00,c2, 00,c1, 00,88, 00,87, 00,86, 00,85, c0,19, 00,6d, 00,3a, 00,c5, 00,89, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, 00,3d, 00,35, 00,c0, c0,38, c0,36, 00,84, 00,95, 00,8d, c0,3d, c0,3f, c0,41, c0,43, c0,45, c0,47, c0,49, c0,4b, c0,4d, c0,4f, c0,65, c0,67, c0,69, c0,71, c0,27, c0,23, c0,13, c0,09, c0,1f, c0,1e, c0,1d, 00,67, 00,40, 00,3f, 00,3e, 00,33, 00,32, 00,31, 00,30, c0,76, c0,72, 00,be, 00,bd, 00,bc, 00,bb, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,18, 00,6c, 00,34, 00,bf, 00,9b, 00,46, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, 00,3c, 00,2f, 00,ba" - cbc_ciphers_hex2="c0,37, c0,35, 00,b6, 00,b2, 00,90, 00,96, 00,41, c0,9a, c0,98, c0,96, 00,ae, c0,94, 00,07, 00,94, 00,8c, 00,21, 00,25, c0,3c, c0,3e, c0,40, c0,42, c0,44, c0,46, c0,48, c0,4a, c0,4c, c0,4e, c0,64, c0,66, c0,68, c0,70, c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,17, 00,1b, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, fe,ff, ff,e0, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,1a, 00,62, 00,09, 00,61, 00,1e, 00,22, fe,fe, ff,e1, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e" - local has_dh_bits="$HAS_DH_BITS" - local -i nr_supported_ciphers=0 sclient_success - local using_sockets=true - local cve="CVE-2013-0169" - local cwe="CWE-310" - local hint="" - local jsonID="LUCKY13" - - if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then - outln - pr_headlineln " Testing for LUCKY13 vulnerability " - outln - fi - pr_bold " LUCKY13"; out " ($cve), experimental " - - if "$TLS13_ONLY"; then - pr_svrty_best "not vulnerable (OK)" - [[ $DEBUG -ge 1 ]] && out ", no CBC ciphers in TLS 1.3 only servers" - outln - fileout "$jsonID" "OK" "not vulnerable, TLS 1.3 only" "$cve" "$cwe" - return 0 - fi - - "$SSL_NATIVE" && using_sockets=false - # The openssl binary distributed has almost everything we need (PSK, KRB5 ciphers and feff, ffe0 are typically missing). - # Measurements show that there's little impact whether we use sockets or TLS here, so the default is sockets here - - if "$using_sockets"; then - tls_sockets "03" "${cbc_ciphers_hex1}, 00,ff" - sclient_success=$? - [[ "$sclient_success" -eq 2 ]] && sclient_success=0 - if [[ $sclient_success -ne 0 ]]; then - tls_sockets "03" "${cbc_ciphers_hex2}, 00,ff" - sclient_success=$? - [[ $sclient_success -eq 2 ]] && sclient_success=0 - fi - else - nr_cbc_ciphers=$(count_ciphers $cbc_ciphers) - nr_supported_ciphers=$(count_ciphers $(actually_supported_osslciphers $cbc_ciphers)) - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -no_ssl2 -cipher $cbc_ciphers -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE /dev/null) - fd_socket 5 "$five_random NOOP" - ;; - *) outln "STARTTLS injection test doesn't work for $SERVICE, yet" - fileout "$jsonID" "INFO" "STARTTLS injection test doesn't work for $SERVICE" "$cve" "$cwe" "$hint" - return 1 - ;; - esac - - uds="$TEMPDIR/uds" - $SOCAT FD:5 UNIX-LISTEN:$uds & - socat_pid=$! - - if "$HAS_UDS"; then - openssl_bin="$OPENSSL" - elif "$HAS_UDS2"; then - openssl_bin="$OPENSSL2" - fi - # normally the interesting fallback we grep later for is in fd2 but we'll catch also stdout here - $openssl_bin s_client -unix $uds >$TMPFILE 2>&1 & - openssl_pid=$! - sleep 1 - - [[ "$DEBUG" -ge 2 ]] && tail $TMPFILE -#FIXME: is the pattern sufficient for SMTP / POP / IMAP? - case $SERVICE in - # Mind all ' ' here! - smtp) grep -Eqa '^250-|^503 ' $TMPFILE && vuln=true ;; - pop3) grep -Eqa '^USER|^PIPELINING|^\+OK ' $TMPFILE && vuln=true ;; - imap) grep -Eqa ' OK NOOP ' $TMPFILE && vuln=true ;; - esac - - if "$vuln"; then - out "likely " - prln_svrty_high "VULNERABLE (NOT ok)" - fileout "$jsonID" "HIGH" "VULNERABLE" "$cve" "$cwe" "$hint" - else - prln_svrty_good "not vulnerable (OK)" - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - fi - - kill $socat_pid 2>/dev/null - kill $openssl_pid 2>/dev/null - close_socket 5 - - tmpfile_handle ${FUNCNAME[0]}.txt - return 0 -} - - -# Test for various server implementation errors that aren't tested for elsewhere. -# Inspired by RFC 8701. -run_grease() { - local -i success - local bug_found=false - local normal_hello_ok=false - local cipher_list proto selected_cipher selected_cipher_hex="" extn rnd_bytes - local alpn_proto alpn alpn_list_len_hex extn_len_hex - local selected_alpn_protocol grease_selected_alpn_protocol - local ciph list temp curve_found - local -i i j rnd alpn_list_len extn_len debug_level="" - local -i ret=0 - # Note: The following values were taken from RFC 8701. - # These arrays may need to be updated if the values change in the final version of this document. - local -a -r grease_cipher_suites=( "0a,0a" "1a,1a" "2a,2a" "3a,3a" "4a,4a" "5a,5a" "6a,6a" "7a,7a" "8a,8a" "9a,9a" "aa,aa" "ba,ba" "ca,ca" "da,da" "ea,ea" "fa,fa" ) - local -a -r grease_supported_groups=( "0a,0a" "1a,1a" "2a,2a" "3a,3a" "4a,4a" "5a,5a" "6a,6a" "7a,7a" "8a,8a" "9a,9a" "aa,aa" "ba,ba" "ca,ca" "da,da" "ea,ea" "fa,fa" ) - local -a -r grease_extn_values=( "0a,0a" "1a,1a" "2a,2a" "3a,3a" "4a,4a" "5a,5a" "6a,6a" "7a,7a" "8a,8a" "9a,9a" "aa,aa" "ba,ba" "ca,ca" "da,da" "ea,ea" "fa,fa" ) - local -r ecdhe_ciphers="cc,14, cc,13, c0,30, c0,2c, c0,28, c0,24, c0,14, c0,0a, c0,9b, cc,a9, cc,a8, c0,af, c0,ad, c0,77, c0,73, c0,19, cc,ac, c0,38, c0,36, c0,49, c0,4d, c0,5d, c0,61, c0,71, c0,87, c0,8b, c0,2f, c0,2b, c0,27, c0,23, c0,13, c0,09, c0,ae, c0,ac, c0,76, c0,72, c0,18, c0,37, c0,35, c0,9a, c0,48, c0,4c, c0,5c, c0,60, c0,70, c0,86, c0,8a, c0,11, c0,07, c0,16, c0,33, c0,12, c0,08, c0,17, c0,34, c0,10, c0,06, c0,15, c0,3b, c0,3a, c0,39" - local jsonID="GREASE" - - outln; pr_headline " Testing for server implementation bugs "; outln "\n" - - # Many of the following checks work by modifying the "basic" call to - # tls_sockets() and assuming the tested-for bug is present if the - # connection fails. However, this only works if the connection succeeds - # with the "basic" call. So, keep trying different "basic" calls until - # one is found that succeeds. - for (( i=0; i < 5; i++ )); do - case $i in - 0) proto="03" ; cipher_list="$TLS12_CIPHER" ;; - 2) proto="02" ; cipher_list="$TLS_CIPHER" ;; - 3) proto="01" ; cipher_list="$TLS_CIPHER" ;; - 4) proto="00" ; cipher_list="$TLS_CIPHER" ;; - esac - tls_sockets "$proto" "$cipher_list" - success=$? - if [[ $success -eq 0 ]] || [[ $success -eq 2 ]]; then - break - fi - done - if [[ $success -eq 0 ]] || [[ $success -eq 2 ]]; then - selected_cipher=$(get_cipher "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - if [[ $TLS_NR_CIPHERS -ne 0 ]]; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - [[ "$selected_cipher" == "${TLS_CIPHER_RFC_NAME[i]}" ]] && selected_cipher_hex="${TLS_CIPHER_HEXCODE[i]}" && break - done - elif "$HAS_SSL2"; then - selected_cipher_hex="$($OPENSSL ciphers -V -tls1 'ALL:COMPLEMENTOFALL' | awk '/'" $selected_cipher "'/ { print $1 }')" - elif "$HAS_CIPHERSUITES"; then - selected_cipher_hex="$($OPENSSL ciphers -V -ciphersuites "$TLS13_OSSL_CIPHERS" 'ALL:COMPLEMENTOFALL'| awk '/'" $selected_cipher "'/ { print $1 }')" - else - selected_cipher_hex="$($OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL'| awk '/'" $selected_cipher "'/ { print $1 }')" - fi - if [[ -n "$selected_cipher_hex" ]]; then - normal_hello_ok=true - selected_cipher_hex="${selected_cipher_hex:2:2},${selected_cipher_hex:7:2}" - fi - else - proto="03" - fi - - # Test for yaSSL bug - server only looks at second byte of each cipher - # suite listed in ClientHello (see issue #793). First check to see if - # server ignores the ciphers in the ClientHello entirely, then check to - # see if server only looks at second byte of each offered cipher. - - # Send a list of non-existent ciphers where the second byte does not match - # any existing cipher. - - # Need to ensure that $TEMPDIR/$NODEIP.parse_tls_serverhello.txt contains the results of the - # most recent calls to tls_sockets even if tls_sockets is not successful. Setting $DEBUG to - # a non-zero value ensures this. Setting it to 1 prevents any extra information from being - # displayed. - debug_level="$DEBUG" - [[ $DEBUG -eq 0 ]] && DEBUG=1 - debugme echo -e "\nSending ClientHello with non-existent ciphers." - tls_sockets "$proto" "de,d0, de,d1, d3,d2, de,d3, 00,ff" - success=$? - if [[ $success -eq 0 ]] || [[ $success -eq 2 ]]; then - prln_svrty_medium " Server claims to support non-existent cipher suite." - fileout "$jsonID" "MEDIUM" "Server claims to support non-existent cipher suite." - bug_found=true - elif grep -q "The ServerHello specifies a cipher suite that wasn't included in the ClientHello" "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ; then - prln_svrty_medium " Server responded with a ServerHello rather than an alert even though it doesn't support any of the client-offered cipher suites." - fileout "$jsonID" "MEDIUM" "Server responded with a ServerHello rather than an alert even though it doesn't support any of the client-offered cipher suites." - bug_found=true - else - # Send a list of non-existent ciphers such that for each cipher that - # is defined, there is one in the list that matches in the second byte - # (but make sure list contains at more 127 ciphers). - debugme echo -e "\nSending ClientHello with non-existent ciphers, but that match existing ciphers in second byte." - tls_sockets "$proto" "de,01, de,02, de,03, de,04, de,05, de,06, de,07, de,08, de,09, de,0a, de,0b, de,0c, de,0d, de,0e, de,0f, de,10, de,11, de,12, de,13, de,14, de,15, de,16, de,17, de,18, de,19, de,1a, de,1b, de,23, de,24, de,25, de,26, de,27, de,28, de,29, de,2a, de,2b, de,2c, de,2d, de,2e, de,2f, de,30, de,31, de,32, de,33, de,34, de,35, de,36, de,37, de,38, de,39, de,3a, de,3b, de,3c, de,3d, de,3e, de,3f, de,40, de,41, de,42, de,43, de,44, de,45, de,46, de,60, de,61, de,62, de,63, de,64, de,65, de,66, de,67, de,68, de,69, de,6a, de,6b, de,6c, de,6d, de,72, de,73, de,74, de,75, de,76, de,77, de,78, de,79, de,84, de,85, de,86, de,87, de,88, de,89, de,96, de,97, de,98, de,99, de,9a, de,9b, de,9c, de,9d, de,9e, de,9f, de,a0, de,a1, de,a2, de,a3, de,a4, de,a5, de,a6, de,a7, de,ba, de,bb, de,bc, de,bd, de,be, de,bf, de,c0, de,c1, de,c2, de,c3, de,c4, de,c5, 00,ff" - success=$? - if [[ $success -eq 0 ]] || [[ $success -eq 2 ]]; then - prln_svrty_medium " Server claims to support non-existent cipher suite." - fileout "$jsonID" "MEDIUM" "Server claims to support non-existent cipher suite." - bug_found=true - elif grep -q " The ServerHello specifies a cipher suite that wasn't included in the ClientHello" "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ; then - prln_svrty_medium " Server only compares against second byte in each cipher suite in ClientHello." - fileout "$jsonID" "MEDIUM" "Server only compares against second byte in each cipher suite in ClientHello." - bug_found=true - fi - fi - DEBUG="$debug_level" - - # Check that server ignores unrecognized extensions - # see RFC 8701 - if "$normal_hello_ok" && [[ "$proto" != "00" ]]; then - # Try multiple different randomly-generated GREASE extensions, - # but make final test use zero-length extension value, just to - # be sure that works before testing server with a zero-length - # extension as the final extension. - for (( i=1; i <= 5; i++ )); do - # Create a random extension using one of the GREASE values. - rnd=$RANDOM%${#grease_extn_values[@]} - extn="${grease_extn_values[rnd]}" - if [[ $i -eq 5 ]]; then - extn_len=0 - else - # Not sure what a good upper bound is here, but a key_share - # extension with an ffdhe8192 would be over 1024 bytes. - extn_len=$RANDOM%1024 - fi - extn_len_hex=$(printf "%04x" $extn_len) - extn+=",${extn_len_hex:0:2},${extn_len_hex:2:2}" - for (( j=0; j <= extn_len-2; j+=2 )); do - rnd_bytes="$(printf "%04x" $RANDOM)" - extn+=",${rnd_bytes:0:2},${rnd_bytes:2:2}" - done - if [[ $j -lt $extn_len ]]; then - rnd_bytes="$(printf "%04x" $RANDOM)" - extn+=",${rnd_bytes:0:2}" - fi - if [[ $DEBUG -ge 2 ]]; then - echo -en "\nSending ClientHello with unrecognized extension" - [[ $DEBUG -ge 3 ]] && echo -n ": $extn" - echo "" - fi - tls_sockets "$proto" "$cipher_list" "" "$extn" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - break - fi - done - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if ClientHello contains an unrecognized extension." - outln " extension used in failed test: $extn" - fileout "$jsonID" "MEDIUM" "Server fails if ClientHello contains an unrecognized extension: $extn" - bug_found=true - else - # Check for inability to handle empty last extension (see PR #792 and - # https://www.ietf.org/mail-archive/web/tls/current/msg19720.html). - # (Since this test also uses an unrecognized extension, only run this - # test if the previous test passed, and use the final extension value - # from that test to ensure that the only difference is the location - # of the extension.) - - # The "extra extensions" parameter needs to include the padding and - # heartbeat extensions, since otherwise prepare_tls_clienthello() - # will add these extensions to the end of the ClientHello. - debugme echo -e "\nSending ClientHello with empty last extension." - tls_sockets "$proto" "$cipher_list" "" " - 00,0f, 00,01, 01, - 00,15, 00,56, - 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, - 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, - 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, - 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, - $extn" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if last extension in ClientHello is empty." - fileout "$jsonID" "MEDIUM" "Server fails if last extension in ClientHello is empty." - bug_found=true - fi - fi - fi - - # Check for SERVER_SIZE_LIMIT_BUG. - # Send a ClientHello with 129 cipher suites (including 0x00,0xff) to see - # if adding a 129th cipher to the list causes a failure. -#TODO: we need to clarify whether the mit is hit at 128 or 129 ciphers. - if "$normal_hello_ok" && [[ "$proto" == 03 ]]; then - debugme echo -e "\nSending ClientHello with 129 cipher suites." - tls_sockets "$proto" "00,27, $cipher_list" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if ClientHello includes more than 128 cipher suites." - fileout "$jsonID" "MEDIUM" "Server fails if ClientHello includes more than 128 cipher suites." - SERVER_SIZE_LIMIT_BUG=true - bug_found=true - fi - fi - - # Check for ClientHello size bug. According to RFC 7586 "at least one TLS - # implementation is known to hang the connection when [a] ClientHello - # record [with a length between 256 and 511 bytes] is received." - # If the length of the host name is more than 75 bytes (which would make - # $SNI more than 87 bytes), then the ClientHello would be more than 511 - # bytes if the server_name extension were included. Removing the SNI - # extension, however, may not be an option, since the server may reject the - # connection attempt for that reason. - if "$normal_hello_ok" && [[ "$proto" != 00 ]] && [[ ${#SNI} -le 87 ]]; then - # Normally prepare_tls_clienthello() will add a padding extension with a length - # that will make the ClientHello be 512 bytes in length. Providing an "extra - # extensions" parameter with a short padding extension prevents that. - debugme echo -e "\nSending ClientHello with length between 256 and 511 bytes." - tls_sockets "$proto" "$cipher_list" "" "00,15,00,01,00" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if ClientHello is between 256 and 511 bytes in length." - fileout "$jsonID" "MEDIUM" "Server fails if ClientHello is between 256 and 511 bytes in length." - bug_found=true - fi - fi - - # Check that server ignores unrecognized cipher suite values - # see RFC 8701 - if "$normal_hello_ok"; then - list="" - for ciph in "${grease_cipher_suites[@]}"; do - list+=", $ciph" - done - debugme echo -e "\nSending ClientHello with unrecognized cipher suite values." - tls_sockets "$proto" "${list:2}, $selected_cipher_hex, 00,ff" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if ClientHello contains unrecognized cipher suite values." - fileout "$jsonID" "MEDIUM" "Server fails if ClientHello contains unrecognized cipher suite values." - bug_found=true - fi - fi - - # Check that servers that support ECDHE cipher suites ignore - # unrecognized named group values. - # see RFC 8701 - if [[ "$proto" != "00" ]]; then - # Send a ClientHello that lists all of the ECDHE cipher suites - tls_sockets "$proto" "$ecdhe_ciphers, 00,ff" "ephemeralkey" - success=$? - if [[ $success -eq 0 ]] || [[ $success -eq 2 ]]; then - # Send the same ClientHello as before but with an unrecognized - # named group value added. Make the unrecognized value the first - # one in the list replacing one of the values in the original list, - # but don't replace the value that was selected by the server. - rnd=$RANDOM%${#grease_supported_groups[@]} - temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") - curve_found="${temp%%,*}" - if [[ "$curve_found" == "ECDH" ]]; then - curve_found="${temp#*, }" - curve_found="${curve_found%%,*}" - fi - if [[ "$curve_found" == "B-571" ]]; then - extn=" - 00, 0a, # Type: Supported Elliptic Curves , see RFC 4492 - 00, 3e, 00, 3c, # lengths - ${grease_supported_groups[rnd]}, 00, 0e, 00, 19, 00, 1c, 00, 1e, 00, 0b, 00, 0c, 00, 1b, - 00, 18, 00, 09, 00, 0a, 00, 1a, 00, 16, 00, 17, 00, 1d, 00, 08, - 00, 06, 00, 07, 00, 14, 00, 15, 00, 04, 00, 05, 00, 12, 00, 13, - 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11" - else - extn=" - 00, 0a, # Type: Supported Elliptic Curves , see RFC 4492 - 00, 3e, 00, 3c, # lengths - ${grease_supported_groups[rnd]}, 00, 0d, 00, 19, 00, 1c, 00, 1e, 00, 0b, 00, 0c, 00, 1b, - 00, 18, 00, 09, 00, 0a, 00, 1a, 00, 16, 00, 17, 00, 1d, 00, 08, - 00, 06, 00, 07, 00, 14, 00, 15, 00, 04, 00, 05, 00, 12, 00, 13, - 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11" - fi - debugme echo -e "\nSending ClientHello with unrecognized named group value in supported_groups extension." - tls_sockets "$proto" "$ecdhe_ciphers, 00,ff" "" "$extn" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if ClientHello contains a supported_groups extension with an unrecognized named group value (${grease_supported_groups[rnd]})." - fileout "$jsonID" "MEDIUM" "Server fails if ClientHello contains a supported_groups extension with an unrecognized named group value (${grease_supported_groups[rnd]})." - bug_found=true - fi - fi - fi - - # Check that servers that support the ALPN extension ignore - # unrecognized ALPN values. - # see RFC 8701 - if "$normal_hello_ok" && [[ -z $STARTTLS ]] && [[ "$proto" != "00" ]]; then - for alpn_proto in $ALPN_PROTOs; do - alpn+=",$(printf "%02x" ${#alpn_proto}),$(string_to_asciihex "$alpn_proto")" - done - alpn_list_len=${#alpn}/3 - alpn_list_len_hex=$(printf "%04x" $alpn_list_len) - extn_len=$alpn_list_len+2 - extn_len_hex=$(printf "%04x" $extn_len) - tls_sockets "$proto" "$cipher_list" "all" "00,10,${extn_len_hex:0:2},${extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if ClientHello contains an application_layer_protocol_negotiation extension." - fileout "$jsonID" "MEDIUM" "Server fails if ClientHello contains an application_layer_protocol_negotiation extension." - bug_found=true - else - selected_alpn_protocol="$(grep "ALPN protocol:" "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" | sed 's/ALPN protocol: //')" - # If using a "normal" ALPN extension worked, then add an unrecognized - # ALPN value to the beginning of the extension and try again. - alpn_proto="ZZ" # "ZZ" = "{0x5A,0x5A}" - alpn=",$(printf "%02x" ${#alpn_proto}),$(string_to_asciihex "$alpn_proto")$alpn" - alpn_list_len=${#alpn}/3 - alpn_list_len_hex=$(printf "%04x" $alpn_list_len) - extn_len=$alpn_list_len+2 - extn_len_hex=$(printf "%04x" $extn_len) - debugme echo -e "\nSending ClientHello with unrecognized ALPN value in application_layer_protocol_negotiation extension." - tls_sockets "$proto" "$cipher_list" "all" "00,10,${extn_len_hex:0:2},${extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn" - success=$? - if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then - prln_svrty_medium " Server fails if ClientHello contains an application_layer_protocol_negotiation extension with an unrecognized ALPN value." - fileout "$jsonID" "MEDIUM" "Server fails if ClientHello contains an application_layer_protocol_negotiation extension with an unrecognized ALPN value." - bug_found=true - else - grease_selected_alpn_protocol="$(grep "ALPN protocol:" "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" | sed 's/ALPN protocol: //')" - if [[ -z "$grease_selected_alpn_protocol" ]] && [[ -n "$selected_alpn_protocol" ]]; then - prln_svrty_medium " Server did not ignore unrecognized ALPN value in the application_layer_protocol_negotiation extension." - fileout "$jsonID" "MEDIUM" "Server did not ignore unrecognized ALPN value in the application_layer_protocol_negotiation extension." - bug_found=true - elif [[ "$grease_selected_alpn_protocol" == $alpn_proto ]]; then - prln_svrty_medium " Server selected GREASE ALPN value ($alpn_proto) in the application_layer_protocol_negotiation extension." - fileout "$jsonID" "MEDIUM" "Server selected GREASE ALPN value ($alpn_proto) in the application_layer_protocol_negotiation extension." - bug_found=true - fi - fi - fi - fi - - # TODO: For servers that support TLSv1.3, check that servers ignore - # an unrecognized named group value along with a corresponding - # unrecognized key share - # see https://www.ietf.org/mail-archive/web/tls/current/msg22322.html - # and https://www.ietf.org/mail-archive/web/tls/current/msg22319.html - - # TODO: For servers that support TLSv1.3, check that servers ignore unrecognized - # values in the supported_versions extension. - # see https://www.ietf.org/mail-archive/web/tls/current/msg22319.html - - # TODO: For servers that support TLSv1.3, check that servers don't require the - # psk_key_exchange_modes extension to be present in the ClientHello. - - if ! "$bug_found"; then - outln " No bugs found." - fileout "$jsonID" "OK" "No bugs found." - #return 0 - else - #return 1 - : - fi - return $ret - #FIXME: No client side error cases where we want to return 1? -} - -# If the server supports any non-PSK cipher suites that use RSA key transport, -# check if the server is vulnerable to Bleichenbacher's Oracle Threat (ROBOT) attacks. -# See "Return Of Bleichenbacher's Oracle Threat (ROBOT)" by Hanno Böck, -# Juraj Somorovsky, and Craig Young (https://robotattack.org). -# -run_robot() { - local tls_hexcode="03" - # A list of all non-PSK cipher suites that use RSA key transport - local cipherlist="00,9d, c0,a1, c0,9d, 00,3d, 00,35, 00,c0, 00,84, c0,3d, c0,51, c0,7b, ff,00, ff,01, ff,02, ff,03, c0,a0, c0,9c, 00,9c, 00,3c, 00,2f, 00,ba, 00,96, 00,41, 00,07, c0,3c, c0,50, c0,7a, 00,05, 00,04, 00,0a, fe,ff, ff,e0, 00,62, 00,09, 00,61, fe,fe, ff,e1, 00,64, 00,60, 00,08, 00,06, 00,03, 00,3b, 00,02, 00,01" - # A list of all non-PSK cipher suites that use RSA key transport and that use AES in either GCM or CBC mode. - local aes_gcm_cbc_cipherlist="00,9d, 00,9c, 00,3d, 00,35, 00,3c, 00,2f" - local padded_pms encrypted_pms cke_prefix client_key_exchange rnd_pad - local rnd_pms="aa112233445566778899112233445566778899112233445566778899112233445566778899112233445566778899" - local rnd_padding_bytes="abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd" - local change_cipher_spec finished resp - local -a response - local -i i subret len iteration testnum pubkeybytes - local pubkeybits - local vulnerable=false send_ccs_finished=true - local -i start_time end_time robottimeout=$MAX_WAITSOCK - local cve="CVE-2017-17382 CVE-2017-17427 CVE-2017-17428 CVE-2017-13098 CVE-2017-1000385 CVE-2017-13099 CVE-2016-6883 CVE-2012-5081 CVE-2017-6168" - local cwe="CWE-203" - local jsonID="ROBOT" - - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for Return of Bleichenbacher's Oracle Threat (ROBOT) vulnerability " && outln - pr_bold " ROBOT " - - if [[ "$STARTTLS_PROTOCOL" =~ irc ]]; then - prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" - return 1 - fi - - if [[ ! "$HAS_PKUTIL" ]]; then - prln_local_problem "Your $OPENSSL does not support the pkeyutl utility." - fileout "$jsonID" "WARN" "$OPENSSL does not support the pkeyutl utility." "$cve" "$cwe" - return 1 - elif ! "$HAS_PKEY"; then - prln_local_problem "Your $OPENSSL does not support the pkey utility." - fileout "$jsonID" "WARN" "$OPENSSL does not support the pkey utility." "$cve" "$cwe" - return 1 - fi - - if [[ 0 -eq $(has_server_protocol tls1_2) ]]; then - tls_hexcode="03" - elif [[ 0 -eq $(has_server_protocol tls1_1) ]]; then - tls_hexcode="02" - elif [[ 0 -eq $(has_server_protocol tls1) ]]; then - tls_hexcode="01" - elif [[ 0 -eq $(has_server_protocol ssl3) ]]; then - tls_hexcode="00" - fi - - # Some hosts are only vulnerable with GCM. First send a list of - # ciphers that use AES in GCM or CBC mode, with the GCM ciphers - # listed first, and then try all ciphers that use RSA key transport - # if there is no connection on the first try. - tls_sockets "$tls_hexcode" "$aes_gcm_cbc_cipherlist, 00,ff" - subret=$? - if [[ $subret -eq 0 ]] || [[ $subret -eq 2 ]]; then - cipherlist="$aes_gcm_cbc_cipherlist" - tls_hexcode="${DETECTED_TLS_VERSION:2:2}" - else - if [[ "$tls_hexcode" != "03" ]]; then - cipherlist="$(strip_inconsistent_ciphers "$tls_hexcode" ", $cipherlist")" - cipherlist="${cipherlist:2}" - fi - tls_sockets "$tls_hexcode" "$cipherlist, 00,ff" - subret=$? - if [[ $subret -eq 2 ]]; then - tls_hexcode="${DETECTED_TLS_VERSION:2:2}" - cipherlist="$(strip_inconsistent_ciphers "$tls_hexcode" ", $cipherlist")" - cipherlist="${cipherlist:2}" - elif [[ $subret -ne 0 ]]; then - prln_svrty_best "Server does not support any cipher suites that use RSA key transport" - fileout "$jsonID" "OK" "not vulnerable, no RSA key transport cipher" "$cve" "$cwe" - return 0 - fi - fi - - # Run the tests in two iterations. In iteration 0, send 5 different client - # key exchange (CKE) messages followed by change cipher spec (CCS) and - # Finished messages, and check whether the server provided the same - # response in each case. If the server didn't provide the same response - # for all five messages in iteration 0, then it is vulnerable. Otherwise - # try a second time (iteration 1) with the same CKE messages, but without - # sending the CCS or Finished messages. - # Iterations 0 and 1 are run with a short timeout waiting for the server - # to respond to the CKE message. If the server was found to be potentially - # vulnerable in iteration 0 or 1 and testssl.sh timed out waiting for a - # response in some cases, then retry the test using a longer timeout value. - for (( iteration=0; iteration < 3; iteration++ )); do - if [[ $iteration -eq 1 ]]; then - # If the server was found to be vulnerable in iteration 0, then - # there's no need to try the alternative message flow. - "$vulnerable" && continue - send_ccs_finished=false - elif [[ $iteration -eq 2 ]]; then - # The tests are being rerun, so reset the vulnerable flag. - vulnerable=false - fi - for (( testnum=0; testnum < 5; testnum++ )); do - response[testnum]="untested" - done - for (( testnum=0; testnum < 5; testnum++ )); do - tls_sockets "$tls_hexcode" "$cipherlist, 00,ff" "all" "" "" "false" - - # Create the padded premaster secret to encrypt. The padding should be - # of the form "00 02 00 ." - # However, for each test except testnum=0 the padding will be - # made incorrect in some way, as specified below. - - # Determine the length of the public key and create the bytes. - # should be a length that makes total length of $padded_pms - # the same as the length of the public key. should contain no 00 bytes. - pubkeybits="$($OPENSSL x509 -noout -pubkey -in $HOSTCERT 2>>$ERRFILE | \ - $OPENSSL pkey -pubin -text_pub 2>>$ERRFILE | awk -F'(' '/Public-Key/ { print $2 }')" - pubkeybits="${pubkeybits%%bit*}" - pubkeybytes=$pubkeybits/8 - [[ $((pubkeybits%8)) -ne 0 ]] && pubkeybytes+=1 - rnd_pad="${rnd_padding_bytes:0:$((2*(pubkeybytes-51)))}" - for (( len=$((${#rnd_pad}/2)); len < pubkeybytes-52; len+=2 )); do - rnd_pad+="abcd" - done - [[ $len -eq $pubkeybytes-52 ]] && rnd_pad+="ab" - - case "$testnum" in - # correct padding - 0) padded_pms="0002${rnd_pad}00${DETECTED_TLS_VERSION}${rnd_pms}" ;; - # wrong first two bytes - 1) padded_pms="4117${rnd_pad}00${DETECTED_TLS_VERSION}${rnd_pms}" ;; - # 0x00 on a wrong position - 2) padded_pms="0002${rnd_pad}11${rnd_pms}0011" ;; - # no 0x00 in the middle - 3) padded_pms="0002${rnd_pad}111111${rnd_pms}" ;; - # wrong version number (according to Klima / Pokorny / Rosa paper) - 4) padded_pms="0002${rnd_pad}000202${rnd_pms}" ;; - esac - - # Encrypt the padded premaster secret using the server's public key. - encrypted_pms="$(hex2binary "$padded_pms" | \ - $OPENSSL pkeyutl -encrypt -certin -inkey $HOSTCERT -pkeyopt rsa_padding_mode:none 2>/dev/null | \ - hexdump -v -e '16/1 "%02x"')" - if [[ -z "$encrypted_pms" ]]; then - if [[ "$DETECTED_TLS_VERSION" == "0300" ]]; then - socksend ",x15, x03, x00, x00, x02, x02, x00" 0 - else - socksend ",x15, x03, x01, x00, x02, x02, x00" 0 - fi - close_socket 5 - prln_fixme "Conversion of public key failed around line $((LINENO - 9))" - fileout "$jsonID" "WARN" "Conversion of public key failed around line $((LINENO - 10)) " - return 1 - fi - - # Create the client key exchange message. - len=${#encrypted_pms}/2 - cke_prefix="16${DETECTED_TLS_VERSION}$(printf "%04x" $((len+6)))10$(printf "%06x" $((len+2)))$(printf "%04x" $len)" - encrypted_pms="$cke_prefix$encrypted_pms" - len=${#encrypted_pms} - client_key_exchange="" - for (( i=0; i/dev/null ; then - readlink -f ls &>/dev/null && \ - TESTSSL_INSTALL_DIR="$(readlink -f "$(basename "${BASH_SOURCE[0]}")")" || \ - TESTSSL_INSTALL_DIR="$(readlink "$(basename "${BASH_SOURCE[0]}")")" - # not sure whether Darwin has -f - TESTSSL_INSTALL_DIR="$(dirname "$TESTSSL_INSTALL_DIR" 2>/dev/null)" - [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" - [[ -r "$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" - fi - - # still no cipher mapping file: - if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && type -p realpath &>/dev/null ; then - TESTSSL_INSTALL_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" - CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" - [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" - fi - - # still no cipher mapping file (and realpath is not present): - if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && type -p readlink &>/dev/null ; then - readlink -f ls &>/dev/null && \ - TESTSSL_INSTALL_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" || \ - TESTSSL_INSTALL_DIR="$(dirname "$(readlink "${BASH_SOURCE[0]}")")" - # not sure whether Darwin has -f - CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" - [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" - fi - - if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]]; then - DISPLAY_CIPHERNAMES="openssl-only" - debugme echo "$CIPHERS_BY_STRENGTH_FILE" - prln_warning "\nATTENTION: No cipher mapping file found!" - outln "Please note from 2.9 on $PROG_NAME needs files in \"\$TESTSSL_INSTALL_DIR/etc/\" to function correctly." - outln - ignore_no_or_lame "Type \"yes\" to ignore this warning and proceed at your own risk" "yes" - [[ $? -ne 0 ]] && exit $ERR_RESOURCE - fi - - TLS_DATA_FILE="$TESTSSL_INSTALL_DIR/etc/tls_data.txt" - if [[ ! -r "$TLS_DATA_FILE" ]]; then - prln_warning "\nATTENTION: No TLS data file found -- needed for socket-based handshakes" - outln "Please note from 2.9 on $PROG_NAME needs files in \"\$TESTSSL_INSTALL_DIR/etc/\" to function correctly." - outln - ignore_no_or_lame "Type \"yes\" to ignore this warning and proceed at your own risk" "yes" - [[ $? -ne 0 ]] && exit $ERR_RESOURCE - else - : # see #705, in a nutshell: not portable to initialize a global array inside a function. Thus it'll be done in main part below - fi -} - - -test_openssl_suffix() { - local naming_ext="$(uname).$(uname -m)" - local uname_arch="$(uname -m)" - local myarch_suffix="" - - [[ $uname_arch =~ 64 ]] && myarch_suffix=64 || myarch_suffix=32 - if [[ -f "$1/openssl" ]] && [[ -x "$1/openssl" ]]; then - OPENSSL="$1/openssl" - return 0 - elif [[ -f "$1/openssl.$naming_ext" ]] && [[ -x "$1/openssl.$naming_ext" ]]; then - OPENSSL="$1/openssl.$naming_ext" - return 0 - elif [[ -f "$1/openssl.$uname_arch" ]] && [[ -x "$1/openssl.$uname_arch" ]]; then - OPENSSL="$1/openssl.$uname_arch" - return 0 - elif [[ -f "$1/openssl$myarch_suffix" ]] && [[ -x "$1/openssl$myarch_suffix" ]]; then - OPENSSL="$1/openssl$myarch_suffix" - return 0 - fi - return 1 -} - - -find_openssl_binary() { - local s_client_has=$TEMPDIR/s_client_has.txt - local s_client_has2=$TEMPDIR/s_client_has2.txt - local s_client_starttls_has=$TEMPDIR/s_client_starttls_has.txt - local s_client_starttls_has2=$TEMPDIR/s_client_starttls_has2 - local openssl_location cwd="" - local ossl_wo_dev_info - local curve - local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13" "ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") - - # 0. check environment variable whether it's executable - if [[ -n "$OPENSSL" ]] && [[ ! -x "$OPENSSL" ]]; then - prln_warning "\ncannot find specified (\$OPENSSL=$OPENSSL) binary." - tmln_out " Looking some place else ..." - elif [[ -x "$OPENSSL" ]]; then - : # 1. all ok supplied $OPENSSL was found and has executable bit set -- testrun comes below - elif [[ -e "/mnt/c/Windows/System32/bash.exe" ]] && test_openssl_suffix "$(dirname "$(type -p openssl)")"; then - # 2. otherwise, only if on Bash on Windows, use system binaries only. - SYSTEM2="WSL" - # Workaround for delayed responses of Windows DNS when using "invalid.", see #1738, #1812. - [[ $NXCONNECT == invalid. ]] && NXCONNECT=127.0.0.1:0 - elif test_openssl_suffix "$TESTSSL_INSTALL_DIR"; then - : # 3. otherwise try openssl in path of testssl.sh - elif test_openssl_suffix "$TESTSSL_INSTALL_DIR/bin"; then - : # 4. otherwise here, this is supposed to be the standard --platform independent path in the future!!! - elif test_openssl_suffix "$(dirname "$(type -p openssl)")"; then - : # 5. we tried hard and failed, so now we use the system binaries - fi - - [[ ! -x "$OPENSSL" ]] && fatal "cannot exec or find any openssl binary" $ERR_OSSLBIN - - # The former detection only was flawed, because when the system supplied openssl.cnf file - # couldn't be parsed by our openssl it bailed out here with a misleading error, see #1982. - # Now we try with another version of the config file and if it still fails we bail out. - if ! $OPENSSL version -d >/dev/null 2>&1 ; then - export OPENSSL_CONF="$TESTSSL_INSTALL_DIR/etc/openssl.cnf" - if ! $OPENSSL version -d >/dev/null 2>&1 ; then - fatal "cannot exec or find any openssl binary" $ERR_OSSLBIN - else - debugme1 echo "We provide our own openssl.cnf file as the one from your system cannot be used" - fi - fi - - # https://www.openssl.org/news/changelog.html - # https://web.archive.org/web/20150815130800/http://openssl.org/news/openssl-notes.html - OSSL_NAME=$($OPENSSL version 2>/dev/null | awk '{ print $1 }') - OSSL_VER=$($OPENSSL version 2>/dev/null | awk -F' ' '{ print $2 }') - OSSL_VER_MAJOR="${OSSL_VER%%\.*}" - ossl_wo_dev_info="${OSSL_VER%%-*}" - OSSL_VER_MINOR="${ossl_wo_dev_info#$OSSL_VER_MAJOR\.}" - OSSL_VER_MINOR="${OSSL_VER_MINOR%%[a-zA-Z]*}" - OSSL_VER_APPENDIX="${OSSL_VER#$OSSL_VER_MAJOR\.$OSSL_VER_MINOR}" - OSSL_VER_PLATFORM=$($OPENSSL version -p 2>/dev/null | sed 's/^platform: //') - OSSL_BUILD_DATE=$($OPENSSL version -a 2>/dev/null | grep '^built' | sed -e 's/built on//' -e 's/: ... //' -e 's/: //' -e 's/ UTC//' -e 's/ +0000//' -e 's/.000000000//') - - # see #190, reverting logic: unless otherwise proved openssl has no dh bits - case "$OSSL_VER_MAJOR.$OSSL_VER_MINOR" in - 1.0.2|1.1.0|1.1.1|3.*) HAS_DH_BITS=true ;; - esac - if [[ "$OSSL_NAME" =~ LibreSSL ]]; then - [[ ${OSSL_VER//./} -ge 210 ]] && HAS_DH_BITS=true - if "$SSL_NATIVE"; then - outln - pr_warning "LibreSSL in native ssl mode is not a good choice for testing INSECURE features!" - fi - fi - - initialize_engine - - openssl_location="$(type -p $OPENSSL)" - [[ -n "$GIT_REL" ]] && \ - cwd="$PWD" || \ - cwd="$RUN_DIR" - if [[ "$openssl_location" == ${PWD}/bin ]]; then - OPENSSL_LOCATION="\$PWD/bin/$(basename "$openssl_location")" - elif [[ "$openssl_location" =~ $cwd ]] && [[ "$cwd" != '.' ]]; then - OPENSSL_LOCATION="${openssl_location%%$cwd}" - else - OPENSSL_LOCATION="$openssl_location" - fi - - OSSL_CIPHERS_S="" - HAS_SSL2=false - HAS_SSL3=false - HAS_TLS13=false - HAS_X448=false - HAS_X25519=false - HAS_SIGALGS=false - HAS_NO_SSL2=false - HAS_NOSERVERNAME=false - HAS_CIPHERSUITES=false - HAS_SECLEVEL=false - HAS_COMP=false - HAS_NO_COMP=false - HAS_CURVES=false - OSSL_SUPPORTED_CURVES="" - HAS_PKEY=false - HAS_PKUTIL=false - HAS_ALPN=false - HAS_NPN=false - HAS_FALLBACK_SCSV=false - HAS_PROXY=false - HAS_XMPP=false - HAS_XMPP_SERVER=false - HAS_XMPP_SERVER2=false - HAS_POSTGRES=false - HAS_MYSQL=false - HAS_LMTP=false - HAS_SIEVE=false - HAS_NNTP=false - HAS_IRC=false - HAS_CHACHA20=false - HAS_AES128_GCM=false - HAS_AES256_GCM=false - HAS_ZLIB=false - HAS_UDS=false - HAS_UDS2=false - TRUSTED1ST="" - HAS_ENABLE_PHA=false - - $OPENSSL ciphers -s 2>&1 | grep -aiq "unknown option" || OSSL_CIPHERS_S="-s" - - $OPENSSL s_client -ssl2 &1 | grep -aiq "unknown option" || HAS_SSL2=true - $OPENSSL s_client -ssl3 &1 | grep -aiq "unknown option" || HAS_SSL3=true - $OPENSSL s_client -tls1_3 &1 | grep -aiq "unknown option" || HAS_TLS13=true - $OPENSSL s_client -no_ssl2 &1 | grep -aiq "unknown option" || HAS_NO_SSL2=true - - $OPENSSL genpkey -algorithm X448 2>&1 | grep -aq "not found" || HAS_X448=true - $OPENSSL genpkey -algorithm X25519 2>&1 | grep -aq "not found" || HAS_X25519=true - $OPENSSL pkey -help 2>&1 | grep -q Error || HAS_PKEY=true - $OPENSSL pkeyutl 2>&1 | grep -q Error || HAS_PKUTIL=true - - # Below and at other occurrences we do a little trick using "$NXCONNECT" to avoid plain and - # link level DNS lookups. See issue #1418 and https://tools.ietf.org/html/rfc6761#section-6.4 - if "$HAS_TLS13"; then - $OPENSSL s_client -tls1_3 -sigalgs PSS+SHA256:PSS+SHA384 -connect $NXCONNECT &1 | grep -aiq "unknown option" || HAS_SIGALGS=true - fi - - $OPENSSL s_client -noservername &1 | grep -aiq "unknown option" || HAS_NOSERVERNAME=true - $OPENSSL s_client -ciphersuites &1 | grep -aiq "unknown option" || HAS_CIPHERSUITES=true - - $OPENSSL ciphers @SECLEVEL=0:ALL > /dev/null 2> /dev/null && HAS_SECLEVEL=true - - $OPENSSL s_client -comp &1 | grep -aiq "unknown option" || HAS_COMP=true - $OPENSSL s_client -no_comp &1 | grep -aiq "unknown option" || HAS_NO_COMP=true - - OPENSSL_NR_CIPHERS=$(count_ciphers "$(actually_supported_osslciphers 'ALL:COMPLEMENTOFALL' 'ALL')") - - # The following statement works with OpenSSL 1.0.2, 1.1.1 and 3.0 and LibreSSL 3.4 - if $OPENSSL s_client -curves &1 | grep -aiq "unknown option"; then - # This is e.g. for LibreSSL (tested with version 3.4.1): WSL users will get "127.0.0.1:0" here, - # all other "invalid.:0". We need a port here, in any case! - # The $OPENSSL connect call deliberately fails: when the curve isn't available with - # "getaddrinfo: Name or service not known", newer LibreSSL with "Failed to set groups". - for curve in "${curves_ossl[@]}"; do - $OPENSSL s_client -groups $curve -connect ${NXCONNECT%:*}:0 &1 | grep -Eiaq "Error with command|unknown option|Failed to set groups" - [[ $? -ne 0 ]] && OSSL_SUPPORTED_CURVES+=" $curve " - done - else - HAS_CURVES=true - for curve in "${curves_ossl[@]}"; do - # Same as above, we just don't need a port for invalid. - $OPENSSL s_client -curves $curve -connect $NXCONNECT &1 | grep -Eiaq "Error with command|unknown option" - [[ $? -ne 0 ]] && OSSL_SUPPORTED_CURVES+=" $curve " - done - fi - - # For the following we feel safe enough to query the s_client help functions. - # That was not good enough for the previous lookups - $OPENSSL s_client -help 2>$s_client_has - $OPENSSL s_client -starttls foo $s_client_starttls_has - - grep -qe '-proxy' $s_client_has && HAS_PROXY=true - grep -qwe '-alpn' $s_client_has && HAS_ALPN=true - grep -qwe '-nextprotoneg' $s_client_has && HAS_NPN=true - - grep -qwe '-fallback_scsv' $s_client_has && HAS_FALLBACK_SCSV=true - - # the output from 1.0.2 and 1.1.1/3.0.x is quite different - grep -q 'xmpp' $s_client_starttls_has && HAS_XMPP=true - grep -Eq 'xmpp-server|xmpp\[-server\]' $s_client_starttls_has && HAS_XMPP_SERVER=true - - grep -q 'postgres' $s_client_starttls_has && HAS_POSTGRES=true - grep -q 'mysql' $s_client_starttls_has && HAS_MYSQL=true - grep -q 'lmtp' $s_client_starttls_has && HAS_LMTP=true - grep -q 'sieve' $s_client_starttls_has && HAS_SIEVE=true - grep -q 'nntp' $s_client_starttls_has && HAS_NNTP=true - grep -q 'irc' $s_client_starttls_has && HAS_IRC=true - - grep -q 'Unix-domain socket' $s_client_has && HAS_UDS=true - - grep -qe '-enable_pha' $s_client_has && HAS_ENABLE_PHA=true - - # Now check whether the standard $OPENSSL has Unix-domain socket and xmpp-server support. If - # not check /usr/bin/openssl -- if available. This is more a kludge which we shouldn't use for - # every openssl feature. At some point we need to decide which with openssl version we go. - OPENSSL2=/usr/bin/openssl - if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ ! $OSSL_VER =~ 1.1.1 ]] && [[ ! $OSSL_VER_MAJOR =~ 3 ]]; then - if [[ -x $OPENSSL2 ]]; then - $OPENSSL2 s_client -help 2>$s_client_has2 - $OPENSSL2 s_client -starttls foo 2>$s_client_starttls_has2 - grep -q 'Unix-domain socket' $s_client_has2 && HAS_UDS2=true - grep -q 'xmpp-server' $s_client_starttls_has2 && HAS_XMPP_SERVER2=true - fi - fi - - $OPENSSL enc -chacha20 -K 12345678901234567890123456789012 -iv 01000000123456789012345678901234 > /dev/null 2> /dev/null <<< "test" - [[ $? -eq 0 ]] && HAS_CHACHA20=true - - $OPENSSL enc -aes-128-gcm -K 0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test" - [[ $? -eq 0 ]] && HAS_AES128_GCM=true - - $OPENSSL enc -aes-256-gcm -K 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef -iv 0123456789abcdef01234567 > /dev/null 2> /dev/null <<< "test" - [[ $? -eq 0 ]] && HAS_AES256_GCM=true - - [[ "$(echo -e "\x78\x9C\xAB\xCA\xC9\x4C\xE2\x02\x00\x06\x20\x01\xBC" | $OPENSSL zlib -d 2>/dev/null)" == zlib ]] && HAS_ZLIB=true - - $OPENSSL verify -trusted_first &1 | grep -q '^usage' || TRUSTED1ST="-trusted_first" - - if [[ -n "$CONNECT_TIMEOUT" ]] || [[ -n "$OPENSSL_TIMEOUT" ]]; then - # We don't set a general timeout as we might not have "timeout" installed and we only - # do what is instructed. Thus we check first what the command line params were, - # then we proceed - if type -p timeout >/dev/null 2>&1; then - # There are different versions of "timeout". Check whether --preserve-status is supported - if timeout --help 2>/dev/null | grep -q 'preserve-status'; then - TIMEOUT_CMD="timeout --preserve-status" - else - TIMEOUT_CMD="timeout" - fi - else - TIMEOUT_CMD="" - outln - fatal "You specified a connect or openssl timeout but the binary \"timeout\" couldn't be found " $ERR_RESOURCE - fi - fi - - if ! "$do_mass_testing"; then - if [[ -n $OPENSSL_TIMEOUT ]]; then - OPENSSL="$TIMEOUT_CMD $OPENSSL_TIMEOUT $OPENSSL" - fi - fi - - return 0 -} - - -find_socat() { - local result"" - - result=$(type -p socat) - if [[ $? -ne 0 ]]; then - return 1 - else - if [[ -x $result ]] && $result -V 2>&1 | grep -iaq 'socat version' ; then - SOCAT=$result - return 0 - fi - fi -} - - -check4openssl_oldfarts() { - case "$OSSL_VER" in - 0.9.7*|0.9.6*|0.9.5*) - # 0.9.5a was latest in 0.9.5 an released 2000/4/1, that'll NOT suffice for this test - old_fart ;; - 0.9.8) - case $OSSL_VER_APPENDIX in - a|b|c|d|e) old_fart;; # no SNI! - # other than that we leave this for MacOSX and FreeBSD but it's a pain and likely gives false negatives/positives - esac - ;; - esac - if [[ $OSSL_VER_MAJOR -lt 1 ]]; then ## mm: Patch for libressl - prln_warning " Your \"$OPENSSL\" is way too old ( /dev/null && HAS_LOCALE=true - if ! "$HAS_LOCALE"; then - # likely docker container or any other minimal environment. This should work(tm) - LC_COLLATE=C - return 0 - fi - - for l in C POSIX C.UTF-8 en_US.UTF-8 en_GB.UTF-8; do - locale -a | grep -q $l - [[ $? -ne 0 ]] && continue - export LC_COLLATE=$l - found=true - break - done - if ! "$found"; then - prln_local_problem "$msg\n" - # we can't use fileout yet as it messes up JSON output, see #2103 - return 1 - fi - return 0 -} - -# This sets the PRINTF command for writing into TCP sockets. It is needed because -# The shell builtin printf flushes the write buffer at every \n, ("\x0a") which -# in turn means a new TCP fragment. That causes a slight performance penalty and -# some F5s to hiccup, see #1113. Unfortunately this can be used only with GNU's -# and OpenBSD's /usr/bin/printf -- FreeBSD + OS X can't do this. Thus here we need -# to pipe through dd or cat, see socksend() and socksend_clienthello(). An empty -# $PRINTF signals the bash internal printf which then uses cat as a stdout buffer. -# A better solution needs to follow. -# -choose_printf() { - local p ptf - - ptf="$(type -aP printf)" - if [[ -n "$ptf" ]]; then - for p in $ptf; do - if $p "\xc0\x14\xc0\xff\xee" | hexdump -C | grep -q 'c0 14 c0 ff ee'; then - PRINTF=$p - return 0 - fi - done - fi - if type -t printf >/dev/null; then - PRINTF="" - return 0 - fi - fatal "Neither external printf nor shell internal found. " $ERR_CLUELESS -} - - -help() { - cat << EOF - - "$PROG_NAME [options] " or "$PROG_NAME " - -"$PROG_NAME