httpclient 2.3.0.1 → 2.8.3

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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +85 -0
  3. data/bin/httpclient +18 -6
  4. data/bin/jsonclient +85 -0
  5. data/lib/http-access2.rb +1 -1
  6. data/lib/httpclient.rb +262 -88
  7. data/lib/httpclient/auth.rb +269 -244
  8. data/lib/httpclient/cacert.pem +3952 -0
  9. data/lib/httpclient/cacert1024.pem +3866 -0
  10. data/lib/httpclient/connection.rb +1 -1
  11. data/lib/httpclient/cookie.rb +161 -514
  12. data/lib/httpclient/http.rb +57 -21
  13. data/lib/httpclient/include_client.rb +2 -0
  14. data/lib/httpclient/jruby_ssl_socket.rb +588 -0
  15. data/lib/httpclient/session.rb +259 -317
  16. data/lib/httpclient/ssl_config.rb +141 -188
  17. data/lib/httpclient/ssl_socket.rb +150 -0
  18. data/lib/httpclient/timeout.rb +1 -1
  19. data/lib/httpclient/util.rb +62 -1
  20. data/lib/httpclient/version.rb +1 -1
  21. data/lib/httpclient/webagent-cookie.rb +459 -0
  22. data/lib/jsonclient.rb +63 -0
  23. data/lib/oauthclient.rb +2 -1
  24. data/sample/jsonclient.rb +67 -0
  25. data/sample/oauth_twitter.rb +4 -4
  26. data/test/{ca-chain.cert → ca-chain.pem} +0 -0
  27. data/test/client-pass.key +18 -0
  28. data/test/helper.rb +10 -8
  29. data/test/jruby_ssl_socket/test_pemutils.rb +32 -0
  30. data/test/test_auth.rb +175 -4
  31. data/test/test_cookie.rb +147 -243
  32. data/test/test_http-access2.rb +17 -16
  33. data/test/test_httpclient.rb +458 -77
  34. data/test/test_jsonclient.rb +80 -0
  35. data/test/test_ssl.rb +341 -17
  36. data/test/test_webagent-cookie.rb +465 -0
  37. metadata +57 -55
  38. data/README.txt +0 -721
  39. data/lib/httpclient/cacert.p7s +0 -1858
  40. data/lib/httpclient/cacert_sha1.p7s +0 -1858
  41. data/sample/oauth_salesforce_10.rb +0 -63
@@ -1,5 +1,5 @@
1
1
  # HTTPClient - HTTP client library.
2
- # Copyright (C) 2000-2009 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
2
+ # Copyright (C) 2000-2015 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
3
3
  #
4
4
  # This program is copyrighted free software by NAKAMURA, Hiroshi. You can
5
5
  # redistribute it and/or modify it under the same terms of Ruby's license;
@@ -20,112 +20,163 @@ class HTTPClient
20
20
  #
21
21
  # == Trust Anchor Control
22
22
  #
23
- # SSLConfig loads 'httpclient/cacert.p7s' as a trust anchor
23
+ # SSLConfig loads 'httpclient/cacert.pem' as a trust anchor
24
24
  # (trusted certificate(s)) with add_trust_ca in initialization time.
25
25
  # This means that HTTPClient instance trusts some CA certificates by default,
26
- # like Web browsers. 'httpclient/cacert.p7s' is created by the author and
27
- # included in released package.
26
+ # like Web browsers. 'httpclient/cacert.pem' is downloaded from curl web
27
+ # site by the author and included in released package.
28
28
  #
29
- # 'cacert.p7s' is automatically generated from JDK 1.6.
29
+ # On JRuby, HTTPClient uses Java runtime's trusted CA certificates, not
30
+ # cacert.pem by default. You can load cacert.pem by calling
31
+ # SSLConfig#load_trust_ca manually like:
32
+ #
33
+ # HTTPClient.new { self.ssl_config.load_trust_ca }.get("https://...")
30
34
  #
31
35
  # You may want to change trust anchor by yourself. Call clear_cert_store
32
36
  # then add_trust_ca for that purpose.
33
37
  class SSLConfig
34
- include OpenSSL if SSLEnabled
38
+ include HTTPClient::Util
39
+ if SSLEnabled
40
+ include OpenSSL
41
+
42
+ module ::OpenSSL
43
+ module X509
44
+ class Store
45
+ attr_reader :_httpclient_cert_store_items
46
+
47
+ # TODO: use prepend instead when we drop JRuby + 1.9.x support
48
+ wrapped = {}
49
+
50
+ wrapped[:initialize] = instance_method(:initialize)
51
+ define_method(:initialize) do |*args|
52
+ wrapped[:initialize].bind(self).call(*args)
53
+ @_httpclient_cert_store_items = [ENV['SSL_CERT_FILE'] || :default]
54
+ end
55
+
56
+ [:add_cert, :add_file, :add_path].each do |m|
57
+ wrapped[m] = instance_method(m)
58
+ define_method(m) do |cert|
59
+ res = wrapped[m].bind(self).call(cert)
60
+ @_httpclient_cert_store_items << cert
61
+ res
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
35
68
 
36
- # String name of OpenSSL's SSL version method name: SSLv2, SSLv23 or SSLv3
37
- attr_reader :ssl_version
38
- # OpenSSL::X509::Certificate:: certificate for SSL client authenticateion.
39
- # nil by default. (no client authenticateion)
40
- attr_reader :client_cert
69
+ class << self
70
+ private
71
+ def attr_config(symbol)
72
+ name = symbol.to_s
73
+ ivar_name = "@#{name}"
74
+ define_method(name) {
75
+ instance_variable_get(ivar_name)
76
+ }
77
+ define_method("#{name}=") { |rhs|
78
+ if instance_variable_get(ivar_name) != rhs
79
+ instance_variable_set(ivar_name, rhs)
80
+ change_notify
81
+ end
82
+ }
83
+ symbol
84
+ end
85
+ end
86
+
87
+
88
+ CIPHERS_DEFAULT = "ALL:!aNULL:!eNULL:!SSLv2" # OpenSSL >1.0.0 default
89
+
90
+ # Which TLS protocol version (also called method) will be used. Defaults
91
+ # to :auto which means that OpenSSL decides (In my tests this resulted
92
+ # with always the highest available protocol being used).
93
+ # String name of OpenSSL's SSL version method name: TLSv1_2, TLSv1_1, TLSv1,
94
+ # SSLv2, SSLv23, SSLv3 or :auto (and nil) to allow version negotiation (default).
95
+ # See {OpenSSL::SSL::SSLContext::METHODS} for a list of available versions
96
+ # in your specific Ruby environment.
97
+ attr_config :ssl_version
98
+ # OpenSSL::X509::Certificate:: certificate for SSL client authentication.
99
+ # nil by default. (no client authentication)
100
+ attr_config :client_cert
41
101
  # OpenSSL::PKey::PKey:: private key for SSL client authentication.
42
- # nil by default. (no client authenticateion)
43
- attr_reader :client_key
102
+ # nil by default. (no client authentication)
103
+ attr_config :client_key
104
+ # OpenSSL::PKey::PKey:: private key pass phrase for client_key.
105
+ # nil by default. (no pass phrase)
106
+ attr_config :client_key_pass
44
107
 
45
108
  # A number which represents OpenSSL's verify mode. Default value is
46
109
  # OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT.
47
- attr_reader :verify_mode
110
+ attr_config :verify_mode
48
111
  # A number of verify depth. Certification path which length is longer than
49
112
  # this depth is not allowed.
50
- attr_reader :verify_depth
113
+ # CAUTION: this is OpenSSL specific option and ignored on JRuby.
114
+ attr_config :verify_depth
51
115
  # A callback handler for custom certificate verification. nil by default.
52
116
  # If the handler is set, handler.call is invoked just after general
53
117
  # OpenSSL's verification. handler.call is invoked with 2 arguments,
54
118
  # ok and ctx; ok is a result of general OpenSSL's verification. ctx is a
55
119
  # OpenSSL::X509::StoreContext.
56
- attr_reader :verify_callback
120
+ attr_config :verify_callback
57
121
  # SSL timeout in sec. nil by default.
58
- attr_reader :timeout
122
+ attr_config :timeout
59
123
  # A number of OpenSSL's SSL options. Default value is
60
124
  # OpenSSL::SSL::OP_ALL | OpenSSL::SSL::OP_NO_SSLv2
61
- attr_reader :options
125
+ # CAUTION: this is OpenSSL specific option and ignored on JRuby.
126
+ # Use ssl_version to specify the TLS version you want to use.
127
+ attr_config :options
62
128
  # A String of OpenSSL's cipher configuration. Default value is
63
129
  # ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH
64
130
  # See ciphers(1) man in OpenSSL for more detail.
65
- attr_reader :ciphers
131
+ attr_config :ciphers
66
132
 
67
133
  # OpenSSL::X509::X509::Store used for verification. You can reset the
68
134
  # store with clear_cert_store and set the new store with cert_store=.
69
135
  attr_reader :cert_store # don't use if you don't know what it is.
70
136
 
71
137
  # For server side configuration. Ignore this.
72
- attr_reader :client_ca # :nodoc:
138
+ attr_config :client_ca # :nodoc:
139
+
140
+ # These array keeps original files/dirs that was added to @cert_store
141
+ def cert_store_items; @cert_store._httpclient_cert_store_items; end
142
+ attr_reader :cert_store_crl_items
73
143
 
74
144
  # Creates a SSLConfig.
75
145
  def initialize(client)
76
146
  return unless SSLEnabled
77
147
  @client = client
78
148
  @cert_store = X509::Store.new
79
- @client_cert = @client_key = @client_ca = nil
149
+ @cert_store_crl_items = []
150
+ @client_cert = @client_key = @client_key_pass = @client_ca = nil
80
151
  @verify_mode = SSL::VERIFY_PEER | SSL::VERIFY_FAIL_IF_NO_PEER_CERT
81
152
  @verify_depth = nil
82
153
  @verify_callback = nil
83
154
  @dest = nil
84
155
  @timeout = nil
85
- @ssl_version = "SSLv3"
86
- @options = defined?(SSL::OP_ALL) ? SSL::OP_ALL | SSL::OP_NO_SSLv2 : nil
156
+ @ssl_version = :auto
157
+ # Follow ruby-ossl's definition
158
+ @options = OpenSSL::SSL::OP_ALL
159
+ @options &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
160
+ @options |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
161
+ @options |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2)
162
+ @options |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3)
87
163
  # OpenSSL 0.9.8 default: "ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH"
88
- @ciphers = "ALL:!aNULL:!eNULL:!SSLv2" # OpenSSL >1.0.0 default
164
+ @ciphers = CIPHERS_DEFAULT
89
165
  @cacerts_loaded = false
90
166
  end
91
167
 
92
- # Sets SSL version method String. Possible values: "SSLv2" for SSL2,
93
- # "SSLv3" for SSL3 and TLS1.x, "SSLv23" for SSL3 with fallback to SSL2.
94
- def ssl_version=(ssl_version)
95
- @ssl_version = ssl_version
96
- change_notify
97
- end
98
-
99
- # Sets certificate (OpenSSL::X509::Certificate) for SSL client
100
- # authentication.
101
- # client_key and client_cert must be a pair.
102
- #
103
- # Calling this method resets all existing sessions.
104
- def client_cert=(client_cert)
105
- @client_cert = client_cert
106
- change_notify
107
- end
108
-
109
- # Sets private key (OpenSSL::PKey::PKey) for SSL client authentication.
110
- # client_key and client_cert must be a pair.
111
- #
112
- # Calling this method resets all existing sessions.
113
- def client_key=(client_key)
114
- @client_key = client_key
115
- change_notify
116
- end
117
-
118
168
  # Sets certificate and private key for SSL client authentication.
119
169
  # cert_file:: must be a filename of PEM/DER formatted file.
120
170
  # key_file:: must be a filename of PEM/DER formatted file. Key must be an
121
171
  # RSA key. If you want to use other PKey algorithm,
122
172
  # use client_key=.
123
173
  #
124
- # Calling this method resets all existing sessions.
125
- def set_client_cert_file(cert_file, key_file)
126
- @client_cert = X509::Certificate.new(File.open(cert_file) { |f| f.read })
127
- @client_key = PKey::RSA.new(File.open(key_file) { |f| f.read })
128
- change_notify
174
+ # Calling this method resets all existing sessions if value is changed.
175
+ def set_client_cert_file(cert_file, key_file, pass = nil)
176
+ if (@client_cert != cert_file) || (@client_key != key_file) || (@client_key_pass != pass)
177
+ @client_cert, @client_key, @client_key_pass = cert_file, key_file, pass
178
+ change_notify
179
+ end
129
180
  end
130
181
 
131
182
  # Sets OpenSSL's default trusted CA certificates. Generally, OpenSSL is
@@ -153,6 +204,7 @@ class HTTPClient
153
204
  def clear_cert_store
154
205
  @cacerts_loaded = true # avoid lazy override
155
206
  @cert_store = X509::Store.new
207
+ @cert_store._httpclient_cert_store_items.clear
156
208
  change_notify
157
209
  end
158
210
 
@@ -161,9 +213,12 @@ class HTTPClient
161
213
  #
162
214
  # Calling this method resets all existing sessions.
163
215
  def cert_store=(cert_store)
164
- @cacerts_loaded = true # avoid lazy override
165
- @cert_store = cert_store
166
- change_notify
216
+ # This is object equality check, since OpenSSL::X509::Store doesn't overload ==
217
+ if !@cacerts_loaded || (@cert_store != cert_store)
218
+ @cacerts_loaded = true # avoid lazy override
219
+ @cert_store = cert_store
220
+ change_notify
221
+ end
167
222
  end
168
223
 
169
224
  # Sets trust anchor certificate(s) for verification.
@@ -174,6 +229,9 @@ class HTTPClient
174
229
  #
175
230
  # Calling this method resets all existing sessions.
176
231
  def add_trust_ca(trust_ca_file_or_hashed_dir)
232
+ unless File.exist?(trust_ca_file_or_hashed_dir)
233
+ trust_ca_file_or_hashed_dir = File.join(File.dirname(__FILE__), trust_ca_file_or_hashed_dir)
234
+ end
177
235
  @cacerts_loaded = true # avoid lazy override
178
236
  add_trust_ca_to_store(@cert_store, trust_ca_file_or_hashed_dir)
179
237
  change_notify
@@ -199,74 +257,30 @@ class HTTPClient
199
257
  # crl:: a OpenSSL::X509::CRL or a filename of a PEM/DER formatted
200
258
  # OpenSSL::X509::CRL.
201
259
  #
260
+ # On JRuby, instead of setting CRL by yourself you can set following
261
+ # options to let HTTPClient to perform revocation check with CRL and OCSP:
262
+ # -J-Dcom.sun.security.enableCRLDP=true -J-Dcom.sun.net.ssl.checkRevocation=true
263
+ # ex. jruby -J-Dcom.sun.security.enableCRLDP=true -J-Dcom.sun.net.ssl.checkRevocation=true app.rb
264
+ #
265
+ # Revoked cert example: https://test-sspev.verisign.com:2443/test-SSPEV-revoked-verisign.html
266
+ #
202
267
  # Calling this method resets all existing sessions.
203
268
  def add_crl(crl)
204
269
  unless crl.is_a?(X509::CRL)
205
270
  crl = X509::CRL.new(File.open(crl) { |f| f.read })
206
271
  end
207
272
  @cert_store.add_crl(crl)
273
+ @cert_store_crl_items << crl
208
274
  @cert_store.flags = X509::V_FLAG_CRL_CHECK | X509::V_FLAG_CRL_CHECK_ALL
209
275
  change_notify
210
276
  end
211
277
  alias set_crl add_crl
212
278
 
213
- # Sets verify mode of OpenSSL. New value must be a combination of
214
- # constants OpenSSL::SSL::VERIFY_*
215
- #
216
- # Calling this method resets all existing sessions.
217
- def verify_mode=(verify_mode)
218
- @verify_mode = verify_mode
219
- change_notify
220
- end
221
-
222
- # Sets verify depth. New value must be a number.
223
- #
224
- # Calling this method resets all existing sessions.
225
- def verify_depth=(verify_depth)
226
- @verify_depth = verify_depth
227
- change_notify
279
+ def verify?
280
+ @verify_mode && (@verify_mode & OpenSSL::SSL::VERIFY_PEER != 0)
228
281
  end
229
282
 
230
- # Sets callback handler for custom certificate verification.
231
- # See verify_callback.
232
- #
233
- # Calling this method resets all existing sessions.
234
- def verify_callback=(verify_callback)
235
- @verify_callback = verify_callback
236
- change_notify
237
- end
238
-
239
- # Sets SSL timeout in sec.
240
- #
241
- # Calling this method resets all existing sessions.
242
- def timeout=(timeout)
243
- @timeout = timeout
244
- change_notify
245
- end
246
-
247
- # Sets SSL options. New value must be a combination of # constants
248
- # OpenSSL::SSL::OP_*
249
- #
250
- # Calling this method resets all existing sessions.
251
- def options=(options)
252
- @options = options
253
- change_notify
254
- end
255
-
256
- # Sets cipher configuration. New value must be a String.
257
- #
258
- # Calling this method resets all existing sessions.
259
- def ciphers=(ciphers)
260
- @ciphers = ciphers
261
- change_notify
262
- end
263
-
264
- def client_ca=(client_ca) # :nodoc:
265
- @client_ca = client_ca
266
- change_notify
267
- end
268
-
269
- # interfaces for SSLSocketWrap.
283
+ # interfaces for SSLSocket.
270
284
  def set_context(ctx) # :nodoc:
271
285
  load_trust_ca unless @cacerts_loaded
272
286
  @cacerts_loaded = true
@@ -276,13 +290,19 @@ class HTTPClient
276
290
  ctx.verify_depth = @verify_depth if @verify_depth
277
291
  ctx.verify_callback = @verify_callback || method(:default_verify_callback)
278
292
  # SSL config
279
- ctx.cert = @client_cert
280
- ctx.key = @client_key
293
+ if @client_cert
294
+ ctx.cert = @client_cert.is_a?(X509::Certificate) ? @client_cert :
295
+ X509::Certificate.new(File.open(@client_cert) { |f| f.read })
296
+ end
297
+ if @client_key
298
+ ctx.key = @client_key.is_a?(PKey::PKey) ? @client_key :
299
+ PKey::RSA.new(File.open(@client_key) { |f| f.read }, @client_key_pass)
300
+ end
281
301
  ctx.client_ca = @client_ca
282
302
  ctx.timeout = @timeout
283
303
  ctx.options = @options
284
304
  ctx.ciphers = @ciphers
285
- ctx.ssl_version = @ssl_version
305
+ ctx.ssl_version = @ssl_version unless @ssl_version == :auto
286
306
  end
287
307
 
288
308
  # post connection check proc for ruby < 1.8.5.
@@ -329,7 +349,7 @@ class HTTPClient
329
349
  depth = ctx.error_depth
330
350
  code = ctx.error
331
351
  msg = ctx.error_string
332
- warn("at depth #{depth} - #{code}: #{msg}")
352
+ warn("at depth #{depth} - #{code}: #{msg}") if $DEBUG
333
353
  end
334
354
  is_ok
335
355
  end
@@ -390,81 +410,14 @@ class HTTPClient
390
410
 
391
411
  def change_notify
392
412
  @client.reset_all
413
+ nil
393
414
  end
394
415
 
416
+ # Use 2048 bit certs trust anchor
395
417
  def load_cacerts(cert_store)
396
- [
397
- [DIST_CERT, 'cacert.p7s'],
398
- [DIST_CERT_SHA1, 'cacert_sha1.p7s']
399
- ].each do |cert_str, ca_file|
400
- file = File.join(File.dirname(__FILE__), ca_file)
401
- if File.exist?(file)
402
- p7 = PKCS7.read_smime(File.open(file) { |f| f.read })
403
- selfcert = X509::Certificate.new(cert_str)
404
- store = X509::Store.new
405
- store.add_cert(selfcert)
406
- if (p7.verify(nil, store, p7.data, 0))
407
- add_trust_ca_to_store(cert_store, file)
408
- return
409
- end
410
- end
411
- end
412
- warn("cacerts loading failed")
418
+ file = File.join(File.dirname(__FILE__), 'cacert.pem')
419
+ add_trust_ca_to_store(cert_store, file)
413
420
  end
414
-
415
- DIST_CERT =<<__DIST_CERT__
416
- -----BEGIN CERTIFICATE-----
417
- MIID/TCCAuWgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBLMQswCQYDVQQGEwJKUDER
418
- MA8GA1UECgwIY3Rvci5vcmcxFDASBgNVBAsMC0RldmVsb3BtZW50MRMwEQYDVQQD
419
- DApodHRwY2xpZW50MB4XDTA5MDUyMTEyMzkwNVoXDTM3MTIzMTIzNTk1OVowSzEL
420
- MAkGA1UEBhMCSlAxETAPBgNVBAoMCGN0b3Iub3JnMRQwEgYDVQQLDAtEZXZlbG9w
421
- bWVudDETMBEGA1UEAwwKaHR0cGNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEP
422
- ADCCAQoCggEBAM2PlkdTH97zvIHoPIMj87wnNvpqIQUD7L/hlysO0XBsmR/XZUeU
423
- ZKB10JQqMXviWpTnU9KU6xGTx3EI4wfd2dpLwH/d4d7K4LngW1kY7kJlZeJhakno
424
- GzQ40RSI9WkQ0R9KOE888f7OkTBafcL8UyWFVIMhQBw2d9iNl4Jc69QojayCDoSX
425
- XbbEP0n8yi7HwIU3RFuX6DtMpOx4/1K7Z002ccOGJ3J9kHgeDQSQtF42cQYC7qj2
426
- 67I/OQgnB7ycxTCP0E7bdXQg+zqsngrhaoNn/+I+CoO7nD4t4uQ+B4agALh4PPxs
427
- bQD9MCL+VurNGLYv0HVd+ZlLblpddC9PLTsCAwEAAaOB6zCB6DAPBgNVHRMBAf8E
428
- BTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09wZW5TU0wgR2VuZXJhdGVkIENl
429
- cnRpZmljYXRlMB0GA1UdDgQWBBRAnB6XlMoOcm7HVAw+JWxY205PHTAOBgNVHQ8B
430
- Af8EBAMCAQYwcwYDVR0jBGwwaoAUQJwel5TKDnJux1QMPiVsWNtOTx2hT6RNMEsx
431
- CzAJBgNVBAYTAkpQMREwDwYDVQQKDAhjdG9yLm9yZzEUMBIGA1UECwwLRGV2ZWxv
432
- cG1lbnQxEzARBgNVBAMMCmh0dHBjbGllbnSCAQEwDQYJKoZIhvcNAQENBQADggEB
433
- ABVFepybD5XqsBnOn/oDHvK0xAPMF4Ap4Ht1yMQLObg8paVhANSdqIevPlCr/mPL
434
- DRjcy+J1fCnE6lCfsfLdTgAjirqt8pm92NccxmJ8hTmMd3LWC1n+eYWaolqTCVRM
435
- Bpe8UY9enyXrFoudHlr9epr18E6As6VrCSfpXFZkD9WHVSWpzkB3qATu5qcDCzCH
436
- bI0755Mdm/1hKJCD4l69h3J3OhRIEUPJfHnPvM5wtiyC2dcE9itwE/wdVzBJeIBX
437
- JQm+Qj+K8qXcRTzZZGIBjw2n46xJgW6YncNCHU/WWfNCYwdkngHS/aN8IbEjhCwf
438
- viXFisVrDN/+pZZGMf67ZaY=
439
- -----END CERTIFICATE-----
440
- __DIST_CERT__
441
-
442
- DIST_CERT_SHA1 =<<__DIST_CERT__
443
- -----BEGIN CERTIFICATE-----
444
- MIID/TCCAuWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJKUDER
445
- MA8GA1UECgwIY3Rvci5vcmcxFDASBgNVBAsMC0RldmVsb3BtZW50MRMwEQYDVQQD
446
- DApodHRwY2xpZW50MB4XDTEwMTIxMzEzNTYyOVoXDTEzMDExNDIzNTk1OVowSzEL
447
- MAkGA1UEBhMCSlAxETAPBgNVBAoMCGN0b3Iub3JnMRQwEgYDVQQLDAtEZXZlbG9w
448
- bWVudDETMBEGA1UEAwwKaHR0cGNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEP
449
- ADCCAQoCggEBAM2PlkdTH97zvIHoPIMj87wnNvpqIQUD7L/hlysO0XBsmR/XZUeU
450
- ZKB10JQqMXviWpTnU9KU6xGTx3EI4wfd2dpLwH/d4d7K4LngW1kY7kJlZeJhakno
451
- GzQ40RSI9WkQ0R9KOE888f7OkTBafcL8UyWFVIMhQBw2d9iNl4Jc69QojayCDoSX
452
- XbbEP0n8yi7HwIU3RFuX6DtMpOx4/1K7Z002ccOGJ3J9kHgeDQSQtF42cQYC7qj2
453
- 67I/OQgnB7ycxTCP0E7bdXQg+zqsngrhaoNn/+I+CoO7nD4t4uQ+B4agALh4PPxs
454
- bQD9MCL+VurNGLYv0HVd+ZlLblpddC9PLTsCAwEAAaOB6zCB6DAPBgNVHRMBAf8E
455
- BTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09wZW5TU0wgR2VuZXJhdGVkIENl
456
- cnRpZmljYXRlMB0GA1UdDgQWBBRAnB6XlMoOcm7HVAw+JWxY205PHTAOBgNVHQ8B
457
- Af8EBAMCAQYwcwYDVR0jBGwwaoAUQJwel5TKDnJux1QMPiVsWNtOTx2hT6RNMEsx
458
- CzAJBgNVBAYTAkpQMREwDwYDVQQKDAhjdG9yLm9yZzEUMBIGA1UECwwLRGV2ZWxv
459
- cG1lbnQxEzARBgNVBAMMCmh0dHBjbGllbnSCAQIwDQYJKoZIhvcNAQEFBQADggEB
460
- AA0kgOPnEDE+Zi/8GmZGmLthazdmigsuMN0pyYd4AJY6RkVeCRUSF4avqBj+lodg
461
- VPC5hgL1k6sMfE3OPTlUMjqaNecWcm9N46VQT2QLYeC6bwpEAgN1KVQ0n6lcUrG+
462
- 8umYZJ+MsdwmBkwSIzIu3ZGwO8IILpNL5fwSMjg7K1T76Po4kPlqmWlcdDUYz5ZY
463
- 42jx3BCFf/w3fuk3mOacZjLu3+AmpHWb+mpXg+jQHfrmVRFCsEkiA2DBLYjE92nB
464
- QmRI2pgn1yHHy7uia+3WHOm72ai3fLSpChctNXTkhFyIB7Q7LYR277fb+GWcvACZ
465
- WHLqjiy2yLPZy9JZwnCi4yE=
466
- -----END CERTIFICATE-----
467
- __DIST_CERT__
468
421
  end
469
422
 
470
423