httpclient 2.3.0.1 → 2.8.3

Sign up to get free protection for your applications and to get access to all the features.
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