ssl-test 1.4.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3e34cb1b1925cf541b7c8022e4c41adb5346214a48b719ec4fa99b7c434bd38
4
- data.tar.gz: 6b577636e88f9741891bc0161b72b921389be95a7b1323f148c26f41e64e2294
3
+ metadata.gz: fa4bf88f0998469b7b82910dcef9f53cc6a64827c5aba691591138b78d33877e
4
+ data.tar.gz: 1666b7fd1b40b3a611d04521041ad64a5a0c6536c3d2fafb3b412ce184c371d5
5
5
  SHA512:
6
- metadata.gz: ad5bbf6ef3f47b7ca645218047ab6b93c3fe497e9233e69bcce3cf7b199bf338dcb358c64b8787b5426235373df76f0d1c8c455a2ee67d9cd3361def51941439
7
- data.tar.gz: 9af52c3812ff2b6c236a592949af4466fe7badbb036f134485847b4db32d53c513c7053fc591f567e091d866ce5078966949053d7cdd37b63163f586db44ad20
6
+ metadata.gz: a40f9e0a498e0ede200cfd6382c24af3b1ab39163b4ac040b4817dff08dc7c320136b3e8516eb5a4fd4f443083da54cf5a822a5736a4795d93de8c7e2581e38b
7
+ data.tar.gz: c51a2d657031506b792960ccd3975521e8cfe5f9c5ffdfd06a7d48a6eacadef63811c4467acc34145d17022de8c3f92ac3a5ccf56316f4766b5ccbefe5fbc9a9
@@ -2,17 +2,15 @@ name: Specs
2
2
  on: [push]
3
3
  jobs:
4
4
  specs:
5
- runs-on: ubuntu-latest
6
- strategy:
7
- matrix:
8
- ruby-version: ['2.6', '2.7', '3.0', '3.1', 'jruby-head', 'truffleruby-head']
5
+ runs-on: ubuntu-22.04
9
6
  steps:
10
7
  - uses: actions/checkout@v2
11
8
  - name: Set up Ruby
12
9
  uses: ruby/setup-ruby@v1
13
10
  with:
14
- ruby-version: ${{ matrix.ruby-version }}
11
+ ruby-version: '3.1'
15
12
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
16
13
  - name: Run specs
17
14
  run: |
15
+ openssl version
18
16
  bundle exec rspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SSLTest [![Build Status](https://travis-ci.com/jarthod/ssl-test.svg?branch=master)](https://travis-ci.com/jarthod/ssl-test)
1
+ # SSLTest
2
2
 
3
3
  A small ruby gem (with no dependencies) to help you test a website's SSL certificate.
4
4
 
@@ -8,68 +8,95 @@ gem 'ssl-test'
8
8
 
9
9
  ## Usage
10
10
 
11
- Simply call the `SSLTest.test` method and it'll return 3 values:
11
+ Simply call the `SSLTest.test_url` method and it'll return 3 values:
12
12
 
13
13
  1. the validity of the certificate
14
14
  2. the error message (if any)
15
15
  3. the certificate itself
16
16
 
17
17
  Example with good cert:
18
+
18
19
  ```ruby
19
- valid, error, cert = SSLTest.test "https://google.com"
20
+ valid, error, cert = SSLTest.test_url "https://google.com"
20
21
  valid # => true
21
22
  error # => nil
22
23
  cert # => #<OpenSSL::X509::Certificate...>
23
24
  ```
24
25
 
25
26
  Example with bad certificate:
27
+
26
28
  ```ruby
27
- valid, error, cert = SSLTest.test "https://testssl-expire.disig.sk"
29
+ valid, error, cert = SSLTest.test_url "https://testssl-expire.disig.sk"
28
30
  valid # => false
29
31
  error # => "error code 10: certificate has expired"
30
32
  cert # => #<OpenSSL::X509::Certificate...>
31
33
  ```
32
34
 
33
35
  If the request fails and we're unable to detemine the validity, here are the returned values:
36
+
34
37
  ```ruby
35
- valid, error, cert = SSLTest.test "https://thisisdefinitelynotawebsite.com"
38
+ valid, error, cert = SSLTest.test_url "https://thisisdefinitelynotawebsite.com"
36
39
  valid # => nil
37
40
  error # => "SSL certificate test failed: getaddrinfo: Name or service not known"
38
41
  cert # => nil
39
42
  ```
40
43
 
41
- You can also pass custom timeout values:
44
+ You can also pass custom timeout values (defaults to 5 seconds for open and read):
45
+
42
46
  ```ruby
43
- valid, error, cert = SSLTest.test "https://slowebsite.com", open_timeout: 2, read_timeout: 2
47
+ valid, error, cert = SSLTest.test_url "https://slowebsite.com", open_timeout: 2, read_timeout: 2
44
48
  valid # => nil
45
49
  error # => "SSL certificate test failed: execution expired"
46
50
  cert # => nil
47
51
  ```
48
- Default timeout values are 5 seconds each (open and read)
49
52
 
50
- Revoked certificates are detected using [OCSP](https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol) endpoint by default:
53
+ Or a proxy host and port to use for the http requests:
54
+
55
+ ```ruby
56
+ valid, error, cert = SSLTest.test_url "https://slowebsite.com", proxy_host: 'localhost', proxy_port: 8080
57
+ valid # => true
58
+ error # => nil
59
+ cert # => #<OpenSSL::X509::Certificate...>
60
+ ```
61
+
62
+ Revoked certificates are detected using [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list) by default:
63
+
51
64
  ```ruby
52
- valid, error, cert = SSLTest.test "https://revoked.badssl.com"
65
+ valid, error, cert = SSLTest.test_url "https://revoked.badssl.com"
53
66
  valid # => false
54
- error # => "SSL certificate revoked: The certificate was revoked for an unknown reason (revocation date: 2019-10-07 20:30:39 UTC)"
67
+ error # => "SSL certificate revoked: Key Compromise (revocation date: 2019-10-07 20:30:39 UTC)"
55
68
  cert # => #<OpenSSL::X509::Certificate...>
56
69
  ```
57
70
 
58
- If the OCSP endpoint is missing, invalid or unreachable the certificate revocation will be tested using [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list).
71
+ If the CRL is missing, invalid or unreachable the certificate revocation will be tested using [OCSP](https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol).
72
+
73
+ If both CRL and OCSP tests are impossible, the certificate will still be considered valid but with an error message:
59
74
 
60
- If both OCSP and CRL tests are impossible, the certificate will still be considered valid but with an error message:
61
75
  ```ruby
62
- valid, error, cert = SSLTest.test "https://sitewithnoOCSPorCRL.com"
76
+ valid, error, cert = SSLTest.test_url "https://sitewithnoOCSPorCRL.com"
63
77
  valid # => true
64
- error # => "Revocation test couldn't be performed: OCSP: Missing OCSP URI in authorityInfoAccess extension, CRL: Missing crlDistributionPoints extension"
78
+ error # => "Revocation test couldn't be performed: CRL: Missing crlDistributionPoints extension, OCSP: Missing OCSP URI in authorityInfoAccess extension"
65
79
  cert # => #<OpenSSL::X509::Certificate...>
66
80
  ```
67
81
 
82
+ ### Testing when you have the client certificate and Certificate Authority Bundle
83
+
84
+ If you already have access to the client certificate and the CA certificate bundle to check against, you can call `test_cert` which takes a certificate and ca bundle certificate instead of a URL. it has all the same options as `test_url`
85
+
86
+ ```ruby
87
+ cert = OpenSSL::X509::Certificate.new(File.read('path/to/certificate')))
88
+ ca_bundle = OpenSSL::X509::Certificate.load(File.read('path/to/ca-bundle-certificate'))
89
+
90
+ valid, error, cert = SSLTest.test_cert(cert, ca_bundle)
91
+ ```
92
+
93
+ This check will pass for self-signed certificates if the certificate is signed by the ca certificate provided.
94
+
68
95
  ## How it works
69
96
 
70
97
  SSLTester connects as an HTTPS client (without issuing any requests) and then closes the connection. It does so using ruby `net/https` library and verifies the SSL status. It also hooks into the validation process to intercept the raw certificate for you.
71
98
 
72
- After that it queries the [OCSP](https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol) endpoint to verify if the certificate has been revoked. If OCSP is not available it'll fetch the [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list) instead. It does this for every certificates in the chain (except the root which is trusted by your Operating System). It is possible the first one will be validated with OCSP and the intermediate with CRL depending on what they offer.
99
+ After that it fetches the [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list) to verify if the certificate has been revoked. If the CRL is not available it'll query the [OCSP](https://en.wikipedia.org/wiki/Online_Certificate_Status_Protocol) endpoint instead. It does this for every certificates in the chain (except the root which is trusted by your Operating System). It is possible the first one will be validated with CRL and the intermediate with OCSP depending on what they offer.
73
100
 
74
101
  ### Caching
75
102
 
@@ -113,11 +140,11 @@ SSLTest will log various messages depending on the log level you specify, exampl
113
140
  ```
114
141
  INFO -- : SSLTest https://www.anonymisation.gov.pf started
115
142
  DEBUG -- : SSLTest + test_chain_revocation: www.anonymisation.gov.pf
143
+ DEBUG -- : SSLTest + CRL: [false, "Missing crlDistributionPoints extension", nil]
116
144
  DEBUG -- : SSLTest + OCSP: fetch URI http://servicesca.ocsp.certigna.fr
117
145
  DEBUG -- : SSLTest + OCSP: 200 OK (4661 bytes)
118
146
  DEBUG -- : SSLTest + OCSP: ocsp_ok
119
147
  DEBUG -- : SSLTest + test_chain_revocation: Certigna Services CA
120
- DEBUG -- : SSLTest + OCSP: [false, "Missing OCSP URI in authorityInfoAccess extension", nil]
121
148
  DEBUG -- : SSLTest + CRL: fetch URI http://crl.certigna.fr/certigna.crl
122
149
  DEBUG -- : SSLTest + CRL: 200 OK (1152 bytes)
123
150
  DEBUG -- : SSLTest + CRL: crl_ok
@@ -140,6 +167,8 @@ But also **revoked certs** like most browsers (not handled by `curl`)
140
167
 
141
168
  See also github releases: https://github.com/jarthod/ssl-test/releases
142
169
 
170
+ * 1.6.0 - 2026-06-16: Check revocation with CRL first and fall back to OCSP (was OCSP first) to reduce revocation detection delay
171
+ * 1.5.0 - 2025-11-28: Add support for local certificates testing and HTTP proxies (#8), changed `#test` method into `#test_url` and `#test_cert` (`#test` remains as an alias for `#test_url` for backward-compatibility)
143
172
  * 1.4.1 - 2022-10-24: Add support for "tcps://" scheme
144
173
  * 1.4.0 - 2021-01-16: Implemented CRL as fallback to OCSP + expose cache metrics + add logger support
145
174
  * 1.3.1 - 2020-04-25: Improved caching of failed OCSP responses (#5)
data/lib/ssl-test/crl.rb CHANGED
@@ -13,9 +13,9 @@ module SSLTest
13
13
  # and building a hash with serial, time and reason takes even more.
14
14
  # So doing this would be MUCH faster in terms of CPU for subsequent tests on the same CRL
15
15
  # but would take a LOT of memory.
16
- # Also I expect most providers to support OCSP for first level cert (a lot of revokation),
17
- # which means we should have to use CRL mostly for intermediaries with much smaller CRL.
18
- # That's what Let's Encrypt is doing with their R3 intermediate for example.
16
+ # Note: we now check CRL first for every cert in the chain (leaf included), so leaf
17
+ # CRLs are fetched and cached too. These can be large for busy CAs, which makes the
18
+ # memory tradeoff above (caching the raw body rather than the parsed list) even more relevant.
19
19
 
20
20
  private
21
21
 
@@ -51,7 +51,7 @@ module SSLTest
51
51
  end
52
52
 
53
53
  # Returns an array with [response, error_message]
54
- def follow_crl_redirects(uri, open_timeout: 5, read_timeout: 5, redirection_limit: 5)
54
+ def follow_crl_redirects(uri, open_timeout: 5, read_timeout: 5, redirection_limit: 5, proxy_host: nil, proxy_port: nil)
55
55
  return [nil, "Too many redirections (> #{redirection_limit})"] if redirection_limit == 0
56
56
 
57
57
  # Return file from cache if not expired
@@ -61,7 +61,7 @@ module SSLTest
61
61
 
62
62
  @logger&.debug { "SSLTest + CRL: fetch URI #{uri}" }
63
63
  path = uri.path == "" ? "/" : uri.path
64
- http = Net::HTTP.new(uri.hostname, uri.port)
64
+ http = Net::HTTP.new(uri.hostname, uri.port, proxy_host, proxy_port)
65
65
  http.open_timeout = open_timeout
66
66
  http.read_timeout = read_timeout
67
67
 
@@ -92,7 +92,7 @@ module SSLTest
92
92
  }
93
93
  [http_response.body, nil]
94
94
  when Net::HTTPRedirection
95
- follow_crl_redirects(URI(http_response["location"]), open_timeout: open_timeout, read_timeout: read_timeout, redirection_limit: redirection_limit - 1)
95
+ follow_crl_redirects(URI(http_response["location"]), open_timeout: open_timeout, read_timeout: read_timeout, proxy_host: proxy_host, proxy_port: proxy_port, redirection_limit: redirection_limit - 1)
96
96
  else
97
97
  @logger&.debug { "SSLTest + CRL: Error: #{http_response.class}" }
98
98
  [nil, "Wrong response type (#{http_response.class})"]
data/lib/ssl-test/ocsp.rb CHANGED
@@ -67,12 +67,12 @@ module SSLTest
67
67
  end
68
68
 
69
69
  # Returns an array with [response, error_message]
70
- def follow_ocsp_redirects(uri, data, open_timeout: 5, read_timeout: 5, redirection_limit: 5)
70
+ def follow_ocsp_redirects(uri, data, open_timeout: 5, read_timeout: 5, redirection_limit: 5, proxy_host: nil, proxy_port: nil)
71
71
  return [nil, "Too many redirections (> #{redirection_limit})"] if redirection_limit == 0
72
72
 
73
73
  @logger&.debug { "SSLTest + OCSP: fetch URI #{uri}" }
74
74
  path = uri.path == "" ? "/" : uri.path
75
- http = Net::HTTP.new(uri.hostname, uri.port)
75
+ http = Net::HTTP.new(uri.hostname, uri.port, proxy_host, proxy_port)
76
76
  http.open_timeout = open_timeout
77
77
  http.read_timeout = read_timeout
78
78
 
@@ -82,7 +82,7 @@ module SSLTest
82
82
  @logger&.debug { "SSLTest + OCSP: 200 OK (#{http_response.body.bytesize} bytes)" }
83
83
  [http_response.body, nil]
84
84
  when Net::HTTPRedirection
85
- follow_ocsp_redirects(URI(http_response["location"]), data, open_timeout: open_timeout, read_timeout: read_timeout, redirection_limit: redirection_limit - 1)
85
+ follow_ocsp_redirects(URI(http_response["location"]), data, open_timeout: open_timeout, read_timeout: read_timeout, proxy_host: proxy_host, proxy_port: proxy_port, redirection_limit: redirection_limit - 1)
86
86
  else
87
87
  @logger&.debug { "SSLTest + OCSP: Error: #{http_response.class}" }
88
88
  [nil, "Wrong response type (#{http_response.class})"]
data/lib/ssl-test.rb CHANGED
@@ -10,16 +10,17 @@ module SSLTest
10
10
  extend OCSP
11
11
  extend CRL
12
12
 
13
- VERSION = -"1.4.1"
13
+ VERSION = -"1.6.0"
14
14
 
15
15
  class << self
16
- def test url, open_timeout: 5, read_timeout: 5, redirection_limit: 5
16
+ def test_url url, open_timeout: 5, read_timeout: 5, proxy_host: nil, proxy_port: nil, redirection_limit: 5
17
+ cert = failed_cert_reason = chain = nil
18
+
17
19
  uri = URI.parse(url)
18
20
  return if uri.scheme != 'https' and uri.scheme != 'tcps'
19
- cert = failed_cert_reason = chain = nil
20
21
 
21
22
  @logger&.info { "SSLTest #{url} started" }
22
- http = Net::HTTP.new(uri.host, uri.port)
23
+ http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port)
23
24
  http.open_timeout = open_timeout
24
25
  http.read_timeout = read_timeout
25
26
  http.use_ssl = true
@@ -33,25 +34,48 @@ module SSLTest
33
34
 
34
35
  begin
35
36
  http.start { }
36
- revoked, message, revocation_date = test_chain_revocation(chain, open_timeout: open_timeout, read_timeout: read_timeout, redirection_limit: redirection_limit)
37
+
38
+ revoked, message, revocation_date = test_chain_revocation(chain, open_timeout: open_timeout, read_timeout: read_timeout, proxy_host: proxy_host, proxy_port: proxy_port, redirection_limit: redirection_limit)
37
39
  @logger&.info { "SSLTest #{url} finished: revoked=#{revoked} #{message}" }
38
- return [false, "SSL certificate revoked: #{message} (revocation date: #{revocation_date})", cert] if revoked
39
- return [true, "Revocation test couldn't be performed: #{message}", cert] if message
40
- return [true, nil, cert]
41
- rescue OpenSSL::SSL::SSLError => e
42
- error = e.message
43
- error = "error code %d: %s" % failed_cert_reason if failed_cert_reason
44
- if error =~ /certificate verify failed/
45
- domains = cert_domains(cert)
46
- if matching_domains(domains, uri.host).none?
47
- error = "hostname \"#{uri.host}\" does not match the server certificate (#{domains.join(', ')})"
48
- end
40
+ return [!revoked, revocation_message(revoked, revocation_date, message), cert]
41
+ rescue OpenSSL::SSL::SSLError => error
42
+ error_message = parse_ssl_error(error, cert, failed_cert_reason, uri:)
43
+ @logger&.info { "SSLTest #{url} finished: #{error_message}" }
44
+ return [false, error_message, cert]
45
+ rescue => error
46
+ @logger&.error { "SSLTest #{url} failed: #{error.message}" }
47
+ return [nil, "SSL certificate test failed: #{error.message}", cert]
48
+ end
49
+ end
50
+ alias :test :test_url
51
+
52
+
53
+ def test_cert client_cert, ca_certs, open_timeout: 5, read_timeout: 5, proxy_host:nil, proxy_port: nil, redirection_limit: 5
54
+ cert = failed_cert_reason = chain = store = nil
55
+
56
+ store = OpenSSL::X509::Store.new
57
+ ca_certs.each { store.add_cert(_1) }
58
+ store.verify_callback = -> (verify_ok, store_context) {
59
+ cert = store_context.current_cert
60
+ chain = store_context.chain
61
+ failed_cert_reason = [store_context.error, store_context.error_string] if store_context.error != 0
62
+ verify_ok
63
+ }
64
+
65
+ begin
66
+ store.verify(client_cert)
67
+
68
+ if failed_cert_reason
69
+ error_message = "error code #{failed_cert_reason[0]}: #{failed_cert_reason[1]}"
70
+ @logger&.info { "SSLTest #{cert.subject.to_s} finished: #{error_message}" }
71
+ return [false, error_message, cert]
72
+ else
73
+ revoked, message, revocation_date = test_chain_revocation(chain, open_timeout: open_timeout, read_timeout: read_timeout, proxy_host: proxy_host, proxy_port: proxy_port, redirection_limit: redirection_limit)
74
+ return [!revoked, revocation_message(revoked, revocation_date, message), cert]
49
75
  end
50
- @logger&.info { "SSLTest #{url} finished: #{error}" }
51
- return [false, error, cert]
52
- rescue => e
53
- @logger&.error { "SSLTest #{url} failed: #{e.message}" }
54
- return [nil, "SSL certificate test failed: #{e.message}", cert]
76
+ rescue => error
77
+ @logger&.error { "SSLTest #{cert.subject.to_s} failed: #{error.message}" }
78
+ return [nil, "SSL certificate test failed: #{error.message}", cert]
55
79
  end
56
80
  end
57
81
 
@@ -81,6 +105,28 @@ module SSLTest
81
105
 
82
106
  private
83
107
 
108
+ def revocation_message(revoked, revocation_date, message)
109
+ if revoked
110
+ "SSL certificate revoked: #{message} (revocation date: #{revocation_date})"
111
+ elsif message
112
+ "Revocation test couldn't be performed: #{message}"
113
+ end
114
+ end
115
+
116
+ def parse_ssl_error(error, cert, failed_cert_reason, uri:)
117
+ message = error.message
118
+ message = "error code %d: %s" % failed_cert_reason if failed_cert_reason
119
+ if message =~ /certificate verify failed/
120
+ domains = cert_domains(cert)
121
+ if !uri.nil? && matching_domains(domains, uri.host).none?
122
+ message = "hostname \"#{uri.host}\" does not match the server certificate (#{domains.join(', ')})"
123
+ end
124
+ end
125
+
126
+ message
127
+ end
128
+
129
+
84
130
  # https://docs.ruby-lang.org/en/2.2.0/OpenSSL/OCSP.html
85
131
  # https://stackoverflow.com/questions/16244084/how-to-programmatically-check-if-a-certificate-has-been-revoked#answer-16257470
86
132
  # Returns an array with [certificate_revoked?, error_reason, revocation_date]
@@ -90,20 +136,20 @@ module SSLTest
90
136
  chain[0..-2].each_with_index do |cert, i|
91
137
  @logger&.debug { "SSLTest + test_chain_revocation: #{cert_field_to_hash(cert.subject)['CN']}" }
92
138
 
93
- # Try with OCSP first
94
- ocsp_result = test_ocsp_revocation(cert, issuer: chain[i + 1], chain: chain, **options)
95
- @logger&.debug { "SSLTest + OCSP: #{ocsp_result}" }
96
- next if ocsp_result == :ocsp_ok # passed, go to next cert
97
- return ocsp_result if ocsp_result[0] == true # revoked
98
-
99
- # Otherwise it means there was an error so let's try with CRL instead
139
+ # Try with CRL first
100
140
  crl_result = test_crl_revocation(cert, issuer: chain[i + 1], chain: chain, **options)
101
141
  @logger&.debug { "SSLTest + CRL: #{crl_result}" }
102
142
  next if crl_result == :crl_ok # passed, go to next cert
103
143
  return crl_result if crl_result[0] == true # revoked
104
144
 
145
+ # Otherwise it means there was an error so let's try with OCSP instead
146
+ ocsp_result = test_ocsp_revocation(cert, issuer: chain[i + 1], chain: chain, **options)
147
+ @logger&.debug { "SSLTest + OCSP: #{ocsp_result}" }
148
+ next if ocsp_result == :ocsp_ok # passed, go to next cert
149
+ return ocsp_result if ocsp_result[0] == true # revoked
150
+
105
151
  # If both method failed, return a soft fail with a combination of both error messages
106
- return [false, "OCSP: #{ocsp_result[1]}, CRL: #{crl_result[1]}", nil]
152
+ return [false, "CRL: #{crl_result[1]}, OCSP: #{ocsp_result[1]}", nil]
107
153
  end
108
154
 
109
155
  # If all test passed, the certificate is not revoked
@@ -0,0 +1,92 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIG7TCCBdWgAwIBAgIQD4I+q2GZA3ujBecwxBeStjANBgkqhkiG9w0BAQsFADBE
3
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMR4wHAYDVQQDExVE
4
+ aWdpQ2VydCBFViBSU0EgQ0EgRzIwHhcNMjYwNjA5MDAwMDAwWhcNMjYwNzI1MjM1
5
+ OTU5WjCBwTETMBEGCysGAQQBgjc8AgEDEwJVUzEVMBMGCysGAQQBgjc8AgECEwRV
6
+ dGFoMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEVMBMGA1UEBRMMNTI5
7
+ OTUzNy0wMTQyMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDENMAsGA1UEBxME
8
+ TGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xGTAXBgNVBAMTEHd3dy5kaWdp
9
+ Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDso4J0VSPj
10
+ 9L8seWfRT+SDm0gw4xANEk34z3gDbVzCUNvAmi5SQIDxoSpUJaVaprR4wpkXT/di
11
+ WJK7uV2iOozOFZ05cHGBmrv/SQAjZjLhKYHgRXQr/Kuu89IH++nxp9WdT12BEzsS
12
+ WDxVRCissVv8LZBNkH3rJDGSqaW8mLTvfF9DKL3ReXsit5/ibELWnYoOwbG1uPvi
13
+ 36Ennp7rR+hckf1bXN638K1/cBQQPAKiv750qxKDwv13XKwV9f3B/3RpRqIUcOAw
14
+ +cuj4nVtWE3+P/pkOEsy7ckH5aV0AIz5bF9prDVSmlYZm69o2Q03cUgt/BqcYkg7
15
+ YqOg203JLBNNAgMBAAGjggNbMIIDVzAfBgNVHSMEGDAWgBRqTlC/mGidW3sgddRZ
16
+ AXlIZpIyBjAdBgNVHQ4EFgQUMxYTQjzRD/R9svhyUBNlsQxeeTowKQYDVR0RBCIw
17
+ IIIQd3d3LmRpZ2ljZXJ0LmNvbYIMZGlnaWNlcnQuY29tMEoGA1UdIARDMEEwCwYJ
18
+ YIZIAYb9bAIBMDIGBWeBDAEBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGln
19
+ aWNlcnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH
20
+ AwEwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp
21
+ Z2lDZXJ0RVZSU0FDQUcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQu
22
+ Y29tL0RpZ2lDZXJ0RVZSU0FDQUcyLmNybDBzBggrBgEFBQcBAQRnMGUwJAYIKwYB
23
+ BQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTA9BggrBgEFBQcwAoYxaHR0
24
+ cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0RVZSU0FDQUcyLmNydDAM
25
+ BgNVHRMBAf8EAjAAMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgDCMX5XRRmj
26
+ Re5/ON6ykEHrx8IhWiK/f9W1rXaa2Q5SzQAAAZ6rBBTHAAAEAwBHMEUCIQClS0CE
27
+ o9NLQgyRRj+NXa6M5vHiMAeQQXdvxrztgEUfpAIgVPxQCT16MQ2CJVoDwW1hP0//
28
+ QEb7cE3fYpJazoOv/+oAdgDXbX0Q0af1d8LH6V/XAL/5gskzWmXh0LMBcxfAyMVp
29
+ dwAAAZ6rBBSRAAAEAwBHMEUCIQC7NRXmFL0D3t/iLvfezwsB/DyzDuXle3u4BA8L
30
+ CT5LigIgZ5Tmcmgzv42s15QbHNEkgpi1DyocInQgxjo3yyVye94AdQCUTkOH+uzB
31
+ 74HzGSQmqBhlAcfTXzgCAT9yZ31VNy4Z2AAAAZ6rBBS1AAAEAwBGMEQCICLSuVkk
32
+ OVVXxrPAzuUj7zs5dpgDAVoVgzQelsixO8H6AiB0bB4SNowTnVZDEJ5knILVRQof
33
+ 4OrJVterjy9djCUUMDANBgkqhkiG9w0BAQsFAAOCAQEAMQ+sL8XkSJozMEFlXm3D
34
+ L5gN/ApjW+Yzz1naeWLuoz5qTO6q2mzB6b5F9PyWJH170xRFcY9DrAqY5KfXq2Pu
35
+ 2ASgUecTeRWTF4HMgelFelPhlqycpHHCBrxLJkI7X9XNG/ZFVT4VdP8LRofpPM8b
36
+ 0eHmt4RkiTKoSpbZbn06nobyb3UD7Snrya8iwMXmdHr5l9rknrmB6eYWbToRB+MN
37
+ PZXeabHjHp+etL8FUMc9HeFwWuI3rB0WstcrSiFtXI2gkdmR3wkMh1lmzTH8XHAx
38
+ 61mAo5VRwqC8zWZ0S1RJOFu7H829vDFetORJUbhIKPaYFEtABdOwkWwexeyc1TH0
39
+ nA==
40
+ -----END CERTIFICATE-----
41
+ -----BEGIN CERTIFICATE-----
42
+ MIIFPDCCBCSgAwIBAgIQAWePH++IIlXYsKcOa3uyIDANBgkqhkiG9w0BAQsFADBh
43
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
44
+ d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
45
+ MjAeFw0yMDA3MDIxMjQyNTBaFw0zMDA3MDIxMjQyNTBaMEQxCzAJBgNVBAYTAlVT
46
+ MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxHjAcBgNVBAMTFURpZ2lDZXJ0IEVWIFJT
47
+ QSBDQSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK0eZsx/neTr
48
+ f4MXJz0R2fJTIDfN8AwUAu7hy4gI0vp7O8LAAHx2h3bbf8wl+pGMSxaJK9ffDDCD
49
+ 63FqqFBqE9eTmo3RkgQhlu55a04LsXRLcK6crkBOO0djdonybmhrfGrtBqYvbRat
50
+ xenkv0Sg4frhRl4wYh4dnW0LOVRGhbt1G5Q19zm9CqMlq7LlUdAE+6d3a5++ppfG
51
+ cnWLmbEVEcLHPAnbl+/iKauQpQlU1Mi+wEBnjE5tK8Q778naXnF+DsedQJ7NEi+b
52
+ QoonTHEz9ryeEcUHuQTv7nApa/zCqes5lXn1pMs4LZJ3SVgbkTLj+RbBov/uiwTX
53
+ tkBEWawvZH8CAwEAAaOCAgswggIHMB0GA1UdDgQWBBRqTlC/mGidW3sgddRZAXlI
54
+ ZpIyBjAfBgNVHSMEGDAWgBROIlQgGJXm427mD/r6uRLtBhePOTAOBgNVHQ8BAf8E
55
+ BAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQI
56
+ MAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
57
+ cC5kaWdpY2VydC5jb20wewYDVR0fBHQwcjA3oDWgM4YxaHR0cDovL2NybDMuZGln
58
+ aWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA3oDWgM4YxaHR0cDov
59
+ L2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDCBzgYD
60
+ VR0gBIHGMIHDMIHABgRVHSAAMIG3MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k
61
+ aWdpY2VydC5jb20vQ1BTMIGKBggrBgEFBQcCAjB+DHxBbnkgdXNlIG9mIHRoaXMg
62
+ Q2VydGlmaWNhdGUgY29uc3RpdHV0ZXMgYWNjZXB0YW5jZSBvZiB0aGUgUmVseWlu
63
+ ZyBQYXJ0eSBBZ3JlZW1lbnQgbG9jYXRlZCBhdCBodHRwczovL3d3dy5kaWdpY2Vy
64
+ dC5jb20vcnBhLXVhMA0GCSqGSIb3DQEBCwUAA4IBAQBSMgrCdY2+O9spnYNvwHiG
65
+ +9lCJbyELR0UsoLwpzGpSdkHD7pVDDFJm3//B8Es+17T1o5Hat+HRDsvRr7d3MEy
66
+ o9iXkkxLhKEgApA2Ft2eZfPrTolc95PwSWnn3FZ8BhdGO4brTA4+zkPSKoMXi/X+
67
+ WLBNN29Z/nbCS7H/qLGt7gViEvTIdU8x+H4l/XigZMUDaVmJ+B5d7cwSK7yOoQdf
68
+ oIBGmA5Mp4LhMzo52rf//kXPfE3wYIZVHqVuxxlnTkFYmffCX9/Lon7SWaGdg6Rc
69
+ k4RHhHLWtmz2lTZ5CEo2ljDsGzCFGJP7oT4q6Q8oFC38irvdKIJ95cUxYzj4tnOI
70
+ -----END CERTIFICATE-----
71
+ -----BEGIN CERTIFICATE-----
72
+ MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
73
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
74
+ d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
75
+ MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
76
+ MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
77
+ b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
78
+ 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
79
+ 2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
80
+ 1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
81
+ q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
82
+ tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
83
+ vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
84
+ BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
85
+ 5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
86
+ 1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
87
+ NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
88
+ Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
89
+ 8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
90
+ pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
91
+ MrY=
92
+ -----END CERTIFICATE-----
@@ -0,0 +1,40 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIG7TCCBdWgAwIBAgIQD4I+q2GZA3ujBecwxBeStjANBgkqhkiG9w0BAQsFADBE
3
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMR4wHAYDVQQDExVE
4
+ aWdpQ2VydCBFViBSU0EgQ0EgRzIwHhcNMjYwNjA5MDAwMDAwWhcNMjYwNzI1MjM1
5
+ OTU5WjCBwTETMBEGCysGAQQBgjc8AgEDEwJVUzEVMBMGCysGAQQBgjc8AgECEwRV
6
+ dGFoMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjEVMBMGA1UEBRMMNTI5
7
+ OTUzNy0wMTQyMQswCQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDENMAsGA1UEBxME
8
+ TGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xGTAXBgNVBAMTEHd3dy5kaWdp
9
+ Y2VydC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDso4J0VSPj
10
+ 9L8seWfRT+SDm0gw4xANEk34z3gDbVzCUNvAmi5SQIDxoSpUJaVaprR4wpkXT/di
11
+ WJK7uV2iOozOFZ05cHGBmrv/SQAjZjLhKYHgRXQr/Kuu89IH++nxp9WdT12BEzsS
12
+ WDxVRCissVv8LZBNkH3rJDGSqaW8mLTvfF9DKL3ReXsit5/ibELWnYoOwbG1uPvi
13
+ 36Ennp7rR+hckf1bXN638K1/cBQQPAKiv750qxKDwv13XKwV9f3B/3RpRqIUcOAw
14
+ +cuj4nVtWE3+P/pkOEsy7ckH5aV0AIz5bF9prDVSmlYZm69o2Q03cUgt/BqcYkg7
15
+ YqOg203JLBNNAgMBAAGjggNbMIIDVzAfBgNVHSMEGDAWgBRqTlC/mGidW3sgddRZ
16
+ AXlIZpIyBjAdBgNVHQ4EFgQUMxYTQjzRD/R9svhyUBNlsQxeeTowKQYDVR0RBCIw
17
+ IIIQd3d3LmRpZ2ljZXJ0LmNvbYIMZGlnaWNlcnQuY29tMEoGA1UdIARDMEEwCwYJ
18
+ YIZIAYb9bAIBMDIGBWeBDAEBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGln
19
+ aWNlcnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH
20
+ AwEwdQYDVR0fBG4wbDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp
21
+ Z2lDZXJ0RVZSU0FDQUcyLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQu
22
+ Y29tL0RpZ2lDZXJ0RVZSU0FDQUcyLmNybDBzBggrBgEFBQcBAQRnMGUwJAYIKwYB
23
+ BQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTA9BggrBgEFBQcwAoYxaHR0
24
+ cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0RVZSU0FDQUcyLmNydDAM
25
+ BgNVHRMBAf8EAjAAMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgDCMX5XRRmj
26
+ Re5/ON6ykEHrx8IhWiK/f9W1rXaa2Q5SzQAAAZ6rBBTHAAAEAwBHMEUCIQClS0CE
27
+ o9NLQgyRRj+NXa6M5vHiMAeQQXdvxrztgEUfpAIgVPxQCT16MQ2CJVoDwW1hP0//
28
+ QEb7cE3fYpJazoOv/+oAdgDXbX0Q0af1d8LH6V/XAL/5gskzWmXh0LMBcxfAyMVp
29
+ dwAAAZ6rBBSRAAAEAwBHMEUCIQC7NRXmFL0D3t/iLvfezwsB/DyzDuXle3u4BA8L
30
+ CT5LigIgZ5Tmcmgzv42s15QbHNEkgpi1DyocInQgxjo3yyVye94AdQCUTkOH+uzB
31
+ 74HzGSQmqBhlAcfTXzgCAT9yZ31VNy4Z2AAAAZ6rBBS1AAAEAwBGMEQCICLSuVkk
32
+ OVVXxrPAzuUj7zs5dpgDAVoVgzQelsixO8H6AiB0bB4SNowTnVZDEJ5knILVRQof
33
+ 4OrJVterjy9djCUUMDANBgkqhkiG9w0BAQsFAAOCAQEAMQ+sL8XkSJozMEFlXm3D
34
+ L5gN/ApjW+Yzz1naeWLuoz5qTO6q2mzB6b5F9PyWJH170xRFcY9DrAqY5KfXq2Pu
35
+ 2ASgUecTeRWTF4HMgelFelPhlqycpHHCBrxLJkI7X9XNG/ZFVT4VdP8LRofpPM8b
36
+ 0eHmt4RkiTKoSpbZbn06nobyb3UD7Snrya8iwMXmdHr5l9rknrmB6eYWbToRB+MN
37
+ PZXeabHjHp+etL8FUMc9HeFwWuI3rB0WstcrSiFtXI2gkdmR3wkMh1lmzTH8XHAx
38
+ 61mAo5VRwqC8zWZ0S1RJOFu7H829vDFetORJUbhIKPaYFEtABdOwkWwexeyc1TH0
39
+ nA==
40
+ -----END CERTIFICATE-----
@@ -0,0 +1,100 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFSzCCBDOgAwIBAgIQSueVSfqavj8QDxekeOFpCTANBgkqhkiG9w0BAQsFADCB
3
+ kDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
4
+ A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNjA0BgNV
5
+ BAMTLUNPTU9ETyBSU0EgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD
6
+ QTAeFw0xNTA0MDkwMDAwMDBaFw0xNTA0MTIyMzU5NTlaMFkxITAfBgNVBAsTGERv
7
+ bWFpbiBDb250cm9sIFZhbGlkYXRlZDEdMBsGA1UECxMUUG9zaXRpdmVTU0wgV2ls
8
+ ZGNhcmQxFTATBgNVBAMUDCouYmFkc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
9
+ ggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2PmzA
10
+ S2BMTOqytMAPgLaw+XLJhgL5XEFdEyt/ccRLvOmULlA3pmccYYz2QULFRtMWhyef
11
+ dOsKnRFSJiFzbIRMeVXk0WvoBj1IFVKtsyjbqv9u/2CVSndrOfEk0TG23U3AxPxT
12
+ uW1CrbV8/q71FdIzSOciccfCFHpsKOo3St/qbLVytH5aohbcabFXRNsKEqveww9H
13
+ dFxBIuGa+RuT5q0iBikusbpJHAwnnqP7i/dAcgCskgjZjFeEU4EFy+b+a1SYQCeF
14
+ xxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaOCAdUwggHRMB8GA1Ud
15
+ IwQYMBaAFJCvajqUWgvYkOoSVnPfQ7Q6KNrnMB0GA1UdDgQWBBSd7sF7gQs6R2lx
16
+ GH0RN5O8pRs/+zAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUE
17
+ FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA6BgsrBgEEAbIxAQIC
18
+ BzArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQUzAI
19
+ BgZngQwBAgEwVAYDVR0fBE0wSzBJoEegRYZDaHR0cDovL2NybC5jb21vZG9jYS5j
20
+ b20vQ09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNybDCB
21
+ hQYIKwYBBQUHAQEEeTB3ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LmNvbW9kb2Nh
22
+ LmNvbS9DT01PRE9SU0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0
23
+ MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wIwYDVR0RBBww
24
+ GoIMKi5iYWRzc2wuY29tggpiYWRzc2wuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBq
25
+ evHa/wMHcnjFZqFPRkMOXxQhjHUa6zbgH6QQFezaMyV8O7UKxwE4PSf9WNnM6i1p
26
+ OXy+l+8L1gtY54x/v7NMHfO3kICmNnwUW+wHLQI+G1tjWxWrAPofOxkt3+IjEBEH
27
+ fnJ/4r+3ABuYLyw/zoWaJ4wQIghBK4o+gk783SHGVnRwpDTysUCeK1iiWQ8dSO/r
28
+ ET7BSp68ZVVtxqPv1dSWzfGuJ/ekVxQ8lEEFeouhN0fX9X3c+s5vMaKwjOrMEpsi
29
+ 8TRwz311SotoKQwe6Zaoz7ASH1wq7mcvf71z81oBIgxw+s1F73hczg36TuHvzmWf
30
+ RwxPuzZEaFZcVlmtqoq8
31
+ -----END CERTIFICATE-----
32
+ -----BEGIN CERTIFICATE-----
33
+ MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB
34
+ hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
35
+ A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
36
+ BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy
37
+ MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
38
+ EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
39
+ Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh
40
+ bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
41
+ ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh
42
+ bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0
43
+ Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6
44
+ ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51
45
+ UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n
46
+ c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY
47
+ MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz
48
+ 30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV
49
+ HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG
50
+ BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv
51
+ bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB
52
+ AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E
53
+ T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v
54
+ ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p
55
+ mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/
56
+ e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps
57
+ P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY
58
+ dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc
59
+ 2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG
60
+ V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4
61
+ HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX
62
+ j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII
63
+ 0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap
64
+ lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf
65
+ +AZxAeKCINT+b72x
66
+ -----END CERTIFICATE-----
67
+ -----BEGIN CERTIFICATE-----
68
+ MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
69
+ hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
70
+ A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
71
+ BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
72
+ MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
73
+ EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
74
+ Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
75
+ dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
76
+ 6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
77
+ pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
78
+ 9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
79
+ /erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
80
+ Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
81
+ +pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
82
+ qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
83
+ SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
84
+ u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
85
+ Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
86
+ crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
87
+ FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
88
+ /wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
89
+ wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
90
+ 4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
91
+ 2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
92
+ FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
93
+ CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
94
+ boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
95
+ jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
96
+ S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
97
+ QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
98
+ 0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
99
+ NVOFBkpdn627G190
100
+ -----END CERTIFICATE-----