httpclient 2.8.3 → 2.9.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 +5 -5
- data/lib/hexdump.rb +12 -12
- data/lib/httpclient/http.rb +8 -8
- data/lib/httpclient/jruby_ssl_socket.rb +14 -8
- data/lib/httpclient/session.rb +2 -2
- data/lib/httpclient/ssl_config.rb +30 -21
- data/lib/httpclient/util.rb +1 -1
- data/lib/httpclient/version.rb +1 -1
- data/lib/httpclient.rb +5 -1
- data/lib/jsonclient.rb +8 -5
- data/sample/auth.rb +1 -1
- data/sample/generate_test_keys.rb +99 -0
- data/test/ca-chain.pem +32 -36
- data/test/ca.cert +16 -19
- data/test/ca.key +27 -0
- data/test/ca.srl +1 -0
- data/test/client-pass.key +30 -18
- data/test/client.cert +17 -16
- data/test/client.key +25 -13
- data/test/fixtures/verify.alt.cert +20 -0
- data/test/fixtures/verify.foo.cert +20 -0
- data/test/fixtures/verify.key +27 -0
- data/test/fixtures/verify.localhost.cert +20 -0
- data/test/helper.rb +5 -7
- data/test/server.cert +16 -15
- data/test/server.key +25 -13
- data/test/subca.cert +16 -17
- data/test/subca.key +27 -0
- data/test/subca.srl +1 -0
- data/test/test_auth.rb +21 -17
- data/test/test_hexdump.rb +1 -2
- data/test/test_http-access2.rb +31 -23
- data/test/test_httpclient.rb +57 -58
- data/test/test_jsonclient.rb +18 -0
- data/test/test_ssl.rb +52 -89
- metadata +31 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e1df0b78f53d502000683d048be1316f156247e5e17995f5fb04a125302bdb4e
|
4
|
+
data.tar.gz: d533eeaf2333f2f35820441a74cdf84075e5227d4fb0648f4e2ea4d2099bd511
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94024e0c5b5bd08800d9b3989151ab919869fabcaed65e4a375490fde0f6ea3b5bfc3ad4a5a9803bb057c5b8d36efc10c6ae5ade8a974c665d443730c63bc7ba
|
7
|
+
data.tar.gz: 768ae9ad96a73740675aca861a81075af3164a4b8875f81368a3228ecfdf523fe6c13cd9355bbe8ddd9155031ff1f908d8ec85e1bd112e0cd31d8b26d809dd6a
|
data/lib/hexdump.rb
CHANGED
@@ -11,13 +11,13 @@ module HexDump
|
|
11
11
|
result = []
|
12
12
|
while raw = str.slice(offset, 16) and raw.length > 0
|
13
13
|
# data field
|
14
|
-
data = ''
|
14
|
+
data = ''.dup
|
15
15
|
for v in raw.unpack('N* a*')
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
if v.kind_of? Integer
|
17
|
+
data << sprintf("%08x ", v)
|
18
|
+
else
|
19
|
+
v.each_byte {|c| data << sprintf("%02x", c) }
|
20
|
+
end
|
21
21
|
end
|
22
22
|
# text field
|
23
23
|
text = raw.tr("\000-\037\177-\377", ".")
|
@@ -25,12 +25,12 @@ module HexDump
|
|
25
25
|
offset += 16
|
26
26
|
# omit duplicate line
|
27
27
|
if /^(#{regex_quote_n(raw)})+/n =~ str[offset .. -1]
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
result << sprintf("%08x ...", offset)
|
29
|
+
offset += $&.length
|
30
|
+
# should print at the end
|
31
|
+
if offset == str.length
|
32
|
+
result << sprintf("%08x %-36s %s", offset-16, data, text)
|
33
|
+
end
|
34
34
|
end
|
35
35
|
end
|
36
36
|
result
|
data/lib/httpclient/http.rb
CHANGED
@@ -238,7 +238,7 @@ module HTTP
|
|
238
238
|
if defined?(Encoding::ASCII_8BIT)
|
239
239
|
def set_body_encoding
|
240
240
|
if type = self.content_type
|
241
|
-
OpenURI::Meta.init(o = '')
|
241
|
+
OpenURI::Meta.init(o = ''.dup)
|
242
242
|
o.meta_add_field('content-type', type)
|
243
243
|
@body_encoding = o.encoding
|
244
244
|
end
|
@@ -491,7 +491,7 @@ module HTTP
|
|
491
491
|
# String.
|
492
492
|
#
|
493
493
|
# assert: @size is not nil
|
494
|
-
def dump(header = '', dev = '')
|
494
|
+
def dump(header = '', dev = ''.dup)
|
495
495
|
if @body.is_a?(Parts)
|
496
496
|
dev << header
|
497
497
|
@body.parts.each do |part|
|
@@ -521,7 +521,7 @@ module HTTP
|
|
521
521
|
# reason. (header is dumped to dev, too)
|
522
522
|
# If no dev (the second argument) given, this method returns a dumped
|
523
523
|
# String.
|
524
|
-
def dump_chunked(header = '', dev = '')
|
524
|
+
def dump_chunked(header = '', dev = ''.dup)
|
525
525
|
dev << header
|
526
526
|
if @body.is_a?(Parts)
|
527
527
|
@body.parts.each do |part|
|
@@ -574,7 +574,7 @@ module HTTP
|
|
574
574
|
end
|
575
575
|
|
576
576
|
def dump_file(io, dev, sz)
|
577
|
-
buf = ''
|
577
|
+
buf = ''.dup
|
578
578
|
rest = sz
|
579
579
|
while rest > 0
|
580
580
|
n = io.read([rest, @chunk_size].min, buf)
|
@@ -585,7 +585,7 @@ module HTTP
|
|
585
585
|
end
|
586
586
|
|
587
587
|
def dump_chunks(io, dev)
|
588
|
-
buf = ''
|
588
|
+
buf = ''.dup
|
589
589
|
while !io.read(@chunk_size, buf).nil?
|
590
590
|
dev << dump_chunk(buf)
|
591
591
|
end
|
@@ -618,8 +618,8 @@ module HTTP
|
|
618
618
|
if Message.file?(part)
|
619
619
|
@as_stream = true
|
620
620
|
@body << part
|
621
|
-
if part.respond_to?(:
|
622
|
-
sz = part.
|
621
|
+
if part.respond_to?(:stat)
|
622
|
+
sz = part.stat.size
|
623
623
|
add_size(part, sz)
|
624
624
|
elsif part.respond_to?(:size)
|
625
625
|
if sz = part.size
|
@@ -954,7 +954,7 @@ module HTTP
|
|
954
954
|
|
955
955
|
# Dumps message (header and body) to given dev.
|
956
956
|
# dev needs to respond to <<.
|
957
|
-
def dump(dev = '')
|
957
|
+
def dump(dev = ''.dup)
|
958
958
|
str = @http_header.dump + CRLF
|
959
959
|
if @http_header.chunked
|
960
960
|
dev = @http_body.dump_chunked(str, dev)
|
@@ -20,14 +20,18 @@ unless defined?(SSLSocket)
|
|
20
20
|
|
21
21
|
BUF_SIZE = 1024 * 16
|
22
22
|
|
23
|
+
def self.normalize_timeout(timeout)
|
24
|
+
[Java::JavaLang::Integer::MAX_VALUE, timeout].min
|
25
|
+
end
|
26
|
+
|
23
27
|
def self.connect(socket, site, opts = {})
|
24
28
|
socket_addr = InetSocketAddress.new(site.host, site.port)
|
25
29
|
if opts[:connect_timeout]
|
26
|
-
socket.connect(socket_addr, opts[:connect_timeout])
|
30
|
+
socket.connect(socket_addr, normalize_timeout(opts[:connect_timeout]))
|
27
31
|
else
|
28
32
|
socket.connect(socket_addr)
|
29
33
|
end
|
30
|
-
socket.setSoTimeout(opts[:so_timeout]) if opts[:so_timeout]
|
34
|
+
socket.setSoTimeout(normalize_timeout(opts[:so_timeout])) if opts[:so_timeout]
|
31
35
|
socket.setKeepAlive(true) if opts[:tcp_keepalive]
|
32
36
|
socket
|
33
37
|
end
|
@@ -491,6 +495,8 @@ unless defined?(SSLSocket)
|
|
491
495
|
ssl_connect(dest.host)
|
492
496
|
rescue java.security.GeneralSecurityException => e
|
493
497
|
raise OpenSSL::SSL::SSLError.new(e.getMessage)
|
498
|
+
rescue java.net.SocketTimeoutException => e
|
499
|
+
raise HTTPClient::ConnectTimeoutError.new(e.getMessage)
|
494
500
|
rescue java.io.IOException => e
|
495
501
|
raise OpenSSL::SSL::SSLError.new("#{e.class}: #{e.getMessage}")
|
496
502
|
end
|
@@ -546,13 +552,13 @@ unless defined?(SSLSocket)
|
|
546
552
|
def create_ssl_socket(socket, dest, config, opts)
|
547
553
|
ctx = create_ssl_context(config)
|
548
554
|
factory = ctx.getSocketFactory
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
JavaSocketWrap.connect(
|
555
|
+
unless socket
|
556
|
+
# Create a plain socket first to set connection timeouts on,
|
557
|
+
# then wrap it in a SSL socket so that SNI gets setup on it.
|
558
|
+
socket = javax.net.SocketFactory.getDefault.createSocket
|
559
|
+
JavaSocketWrap.connect(socket, dest, opts)
|
554
560
|
end
|
555
|
-
|
561
|
+
factory.createSocket(socket, dest.host, dest.port, true)
|
556
562
|
end
|
557
563
|
|
558
564
|
def peer_cert
|
data/lib/httpclient/session.rb
CHANGED
@@ -21,7 +21,7 @@ require 'zlib'
|
|
21
21
|
require 'httpclient/timeout' # TODO: remove this once we drop 1.8 support
|
22
22
|
require 'httpclient/ssl_config'
|
23
23
|
require 'httpclient/http'
|
24
|
-
if
|
24
|
+
if defined? JRUBY_VERSION
|
25
25
|
require 'httpclient/jruby_ssl_socket'
|
26
26
|
else
|
27
27
|
require 'httpclient/ssl_socket'
|
@@ -950,7 +950,7 @@ class HTTPClient
|
|
950
950
|
end
|
951
951
|
|
952
952
|
def empty_bin_str
|
953
|
-
str = ''
|
953
|
+
str = ''.dup
|
954
954
|
str.force_encoding('BINARY') if str.respond_to?(:force_encoding)
|
955
955
|
str
|
956
956
|
end
|
@@ -39,26 +39,28 @@ class HTTPClient
|
|
39
39
|
if SSLEnabled
|
40
40
|
include OpenSSL
|
41
41
|
|
42
|
-
|
43
|
-
module
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
42
|
+
if defined? JRUBY_VERSION
|
43
|
+
module ::OpenSSL
|
44
|
+
module X509
|
45
|
+
class Store
|
46
|
+
attr_reader :_httpclient_cert_store_items
|
47
|
+
|
48
|
+
# TODO: use prepend instead when we drop JRuby + 1.9.x support
|
49
|
+
wrapped = {}
|
50
|
+
|
51
|
+
wrapped[:initialize] = instance_method(:initialize)
|
52
|
+
define_method(:initialize) do |*args|
|
53
|
+
wrapped[:initialize].bind(self).call(*args)
|
54
|
+
@_httpclient_cert_store_items = [ENV['SSL_CERT_FILE'] || :default]
|
55
|
+
end
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
[:add_cert, :add_file, :add_path].each do |m|
|
58
|
+
wrapped[m] = instance_method(m)
|
59
|
+
define_method(m) do |cert|
|
60
|
+
res = wrapped[m].bind(self).call(cert)
|
61
|
+
@_httpclient_cert_store_items << cert
|
62
|
+
res
|
63
|
+
end
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -138,7 +140,9 @@ class HTTPClient
|
|
138
140
|
attr_config :client_ca # :nodoc:
|
139
141
|
|
140
142
|
# These array keeps original files/dirs that was added to @cert_store
|
141
|
-
|
143
|
+
if defined? JRUBY_VERSION
|
144
|
+
def cert_store_items; @cert_store._httpclient_cert_store_items; end
|
145
|
+
end
|
142
146
|
attr_reader :cert_store_crl_items
|
143
147
|
|
144
148
|
# Creates a SSLConfig.
|
@@ -204,7 +208,9 @@ class HTTPClient
|
|
204
208
|
def clear_cert_store
|
205
209
|
@cacerts_loaded = true # avoid lazy override
|
206
210
|
@cert_store = X509::Store.new
|
207
|
-
|
211
|
+
if defined? JRUBY_VERSION
|
212
|
+
@cert_store._httpclient_cert_store_items.clear
|
213
|
+
end
|
208
214
|
change_notify
|
209
215
|
end
|
210
216
|
|
@@ -403,6 +409,9 @@ class HTTPClient
|
|
403
409
|
return true
|
404
410
|
end
|
405
411
|
|
412
|
+
if pathlen > 2
|
413
|
+
warn('pathlen > 2') if $DEBUG
|
414
|
+
end
|
406
415
|
return false
|
407
416
|
end
|
408
417
|
|
data/lib/httpclient/util.rb
CHANGED
data/lib/httpclient/version.rb
CHANGED
data/lib/httpclient.rb
CHANGED
@@ -753,6 +753,10 @@ class HTTPClient
|
|
753
753
|
request(:patch, uri, new_args, &block)
|
754
754
|
end
|
755
755
|
|
756
|
+
# :call-seq:
|
757
|
+
# post(uri, {query: query, body: body, header: header, follow_redirect: follow_redirect}) -> HTTP::Message
|
758
|
+
# post(uri, body, header, follow_redirect) -> HTTP::Message
|
759
|
+
#
|
756
760
|
# Sends POST request to the specified URL. See request for arguments.
|
757
761
|
# You should not depend on :follow_redirect => true for POST method. It
|
758
762
|
# sends the same POST method to the new location which is prohibited in HTTP spec.
|
@@ -1236,7 +1240,7 @@ private
|
|
1236
1240
|
conn.push(res)
|
1237
1241
|
return res
|
1238
1242
|
end
|
1239
|
-
content = block ? nil : ''
|
1243
|
+
content = block ? nil : ''.dup
|
1240
1244
|
res = HTTP::Message.new_response(content, req.header)
|
1241
1245
|
@debug_dev << "= Request\n\n" if @debug_dev
|
1242
1246
|
sess = @session_manager.query(req, proxy)
|
data/lib/jsonclient.rb
CHANGED
@@ -2,7 +2,7 @@ require 'httpclient'
|
|
2
2
|
require 'json'
|
3
3
|
|
4
4
|
# JSONClient auto-converts Hash <-> JSON in request and response.
|
5
|
-
# * For POST or PUT request, convert Hash body to JSON String with 'application/json; charset=utf-8' header.
|
5
|
+
# * For PATCH, POST or PUT request, convert Hash body to JSON String with 'application/json; charset=utf-8' header.
|
6
6
|
# * For response, convert JSON String to Hash when content-type is '(application|text)/(x-)?json'
|
7
7
|
class JSONClient < HTTPClient
|
8
8
|
CONTENT_TYPE_JSON_REGEX = /(application|text)\/(x-)?json/i
|
@@ -17,6 +17,10 @@ class JSONClient < HTTPClient
|
|
17
17
|
@content_type_json_response_regex = CONTENT_TYPE_JSON_REGEX
|
18
18
|
end
|
19
19
|
|
20
|
+
def patch(uri, *args, &block)
|
21
|
+
request(:patch, uri, argument_to_hash_for_json(args), &block)
|
22
|
+
end
|
23
|
+
|
20
24
|
def post(uri, *args, &block)
|
21
25
|
request(:post, uri, argument_to_hash_for_json(args), &block)
|
22
26
|
end
|
@@ -37,7 +41,7 @@ private
|
|
37
41
|
|
38
42
|
def argument_to_hash_for_json(args)
|
39
43
|
hash = argument_to_hash(args, :body, :header, :follow_redirect)
|
40
|
-
if hash[:body].is_a?(Hash)
|
44
|
+
if hash[:body].is_a?(Hash) || hash[:body].is_a?(Array)
|
41
45
|
hash[:header] = json_header(hash[:header])
|
42
46
|
hash[:body] = JSON.generate(hash[:body])
|
43
47
|
end
|
@@ -47,11 +51,10 @@ private
|
|
47
51
|
def json_header(header)
|
48
52
|
header ||= {}
|
49
53
|
if header.is_a?(Hash)
|
50
|
-
header
|
54
|
+
header.merge('Content-Type' => @content_type_json_request)
|
51
55
|
else
|
52
|
-
header
|
56
|
+
header + [['Content-Type', @content_type_json_request]]
|
53
57
|
end
|
54
|
-
header
|
55
58
|
end
|
56
59
|
|
57
60
|
def wrap_json_response(original)
|
data/sample/auth.rb
CHANGED
@@ -7,5 +7,5 @@ c.debug_dev = STDOUT
|
|
7
7
|
#c.set_proxy_auth("admin", "admin")
|
8
8
|
|
9
9
|
# for WWW authentication: supports Basic, Digest and Negotiate.
|
10
|
-
c.set_auth("http://dev.ctor.org/http-access2/", "
|
10
|
+
c.set_auth("http://dev.ctor.org/http-access2/", "username", "password")
|
11
11
|
p c.get("http://dev.ctor.org/http-access2/login")
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require "openssl"
|
2
|
+
|
3
|
+
def build_ca
|
4
|
+
root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
|
5
|
+
root_ca = OpenSSL::X509::Certificate.new
|
6
|
+
root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
|
7
|
+
root_ca.serial = 1
|
8
|
+
root_ca.subject = OpenSSL::X509::Name.parse "C=JP,O=JIN.GR.JP,OU=RRR,CN=CA"
|
9
|
+
root_ca.issuer = root_ca.subject # root CA's are "self-signed"
|
10
|
+
root_ca.public_key = root_key.public_key
|
11
|
+
root_ca.not_before = Time.now
|
12
|
+
root_ca.not_after = root_ca.not_before + 10 * 365 * 24 * 60 * 60 # 10 years validity
|
13
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
14
|
+
ef.subject_certificate = root_ca
|
15
|
+
ef.issuer_certificate = root_ca
|
16
|
+
root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
|
17
|
+
root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
|
18
|
+
root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
19
|
+
root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
|
20
|
+
root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
|
21
|
+
[root_key, root_ca]
|
22
|
+
end
|
23
|
+
|
24
|
+
root_key, root_ca = build_ca
|
25
|
+
|
26
|
+
File.write("test/ca.cert", root_ca.to_s)
|
27
|
+
File.write("test/ca.key", root_key.to_s)
|
28
|
+
|
29
|
+
def sub_cert(root_key, root_ca, cn, intermediate: false)
|
30
|
+
key = OpenSSL::PKey::RSA.new 2048
|
31
|
+
cert = OpenSSL::X509::Certificate.new
|
32
|
+
cert.version = 2
|
33
|
+
cert.serial = 2
|
34
|
+
cert.subject = OpenSSL::X509::Name.parse "C=JP,O=JIN.GR.JP,OU=RRR,CN=#{cn}"
|
35
|
+
cert.issuer = root_ca.subject # root CA is the issuer
|
36
|
+
cert.public_key = key.public_key
|
37
|
+
cert.not_before = Time.now
|
38
|
+
cert.not_after = cert.not_before + 9 * 365 * 24 * 60 * 60 # 9 years validity
|
39
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
40
|
+
ef.subject_certificate = cert
|
41
|
+
ef.issuer_certificate = root_ca
|
42
|
+
cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
43
|
+
if intermediate
|
44
|
+
cert.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
|
45
|
+
cert.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
|
46
|
+
else
|
47
|
+
cert.add_extension(ef.create_extension("keyUsage","digitalSignature, keyEncipherment", true))
|
48
|
+
cert.add_extension(ef.create_extension("extendedKeyUsage", "serverAuth"))
|
49
|
+
end
|
50
|
+
cert.sign(root_key, OpenSSL::Digest::SHA256.new)
|
51
|
+
[key, cert]
|
52
|
+
end
|
53
|
+
|
54
|
+
sub_key, sub_cert = sub_cert(root_key, root_ca, "SubCA", intermediate: true)
|
55
|
+
File.write("test/subca.cert", sub_cert.to_s)
|
56
|
+
File.write("test/subca.key", sub_key.to_s)
|
57
|
+
|
58
|
+
server_key, server_cert = sub_cert(sub_key, sub_cert, "localhost")
|
59
|
+
File.write("test/server.cert", server_cert.to_s)
|
60
|
+
File.write("test/server.key", server_key.to_s)
|
61
|
+
|
62
|
+
client_key, client_cert = sub_cert(root_key, root_ca, "localhost")
|
63
|
+
File.write("test/client.cert", client_cert.to_s)
|
64
|
+
File.write("test/client.key", client_key.to_s)
|
65
|
+
|
66
|
+
system(
|
67
|
+
"openssl", "rsa", "-aes256",
|
68
|
+
"-in", "test/client.key",
|
69
|
+
"-out", "test/client-pass.key",
|
70
|
+
"-passout", "pass:pass4key",
|
71
|
+
)
|
72
|
+
|
73
|
+
File.write("test/ca-chain.pem", root_ca.to_s + sub_cert.to_s)
|
74
|
+
|
75
|
+
verify_key = OpenSSL::PKey::RSA.new 2048
|
76
|
+
File.write("test/fixtures/verify.key", verify_key.to_s)
|
77
|
+
|
78
|
+
def build_self_signed(key, cn)
|
79
|
+
cert = OpenSSL::X509::Certificate.new
|
80
|
+
cert.version = 2
|
81
|
+
cert.serial = 2
|
82
|
+
cert.subject = OpenSSL::X509::Name.parse "C=JP,O=JIN.GR.JP,OU=RRR,CN=#{cn}"
|
83
|
+
cert.issuer = cert.subject
|
84
|
+
cert.public_key = key.public_key
|
85
|
+
cert.not_before = Time.now
|
86
|
+
cert.not_after = cert.not_before + 9 * 365 * 24 * 60 * 60 # 9 years validity
|
87
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
88
|
+
ef.subject_certificate = cert
|
89
|
+
ef.issuer_certificate = cert
|
90
|
+
cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
|
91
|
+
cert.add_extension(ef.create_extension("keyUsage","digitalSignature, keyEncipherment", true))
|
92
|
+
cert.add_extension(ef.create_extension("extendedKeyUsage", "serverAuth"))
|
93
|
+
cert.sign(key, OpenSSL::Digest::SHA256.new)
|
94
|
+
cert
|
95
|
+
end
|
96
|
+
|
97
|
+
File.write("test/fixtures/verify.localhost.cert", build_self_signed(verify_key, "localhost").to_s)
|
98
|
+
File.write("test/fixtures/verify.foo.cert", build_self_signed(verify_key, "foo").to_s)
|
99
|
+
File.write("test/fixtures/verify.alt.cert", build_self_signed(verify_key, "alt").to_s)
|
data/test/ca-chain.pem
CHANGED
@@ -1,44 +1,40 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
|
2
|
+
MIIDVjCCAj6gAwIBAgIBATANBgkqhkiG9w0BAQsFADA8MQswCQYDVQQGEwJKUDES
|
3
3
|
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
4
|
-
|
4
|
+
DTI1MDIxMjA4NDIzMVoXDTM1MDIxMDA4NDIzMVowPDELMAkGA1UEBhMCSlAxEjAQ
|
5
5
|
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
|
21
|
-
PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
|
22
|
-
d/xgcK06UVQRL/HbEYGiQL056mc=
|
6
|
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJqxQwHle/gAbPM1QabhCqWiAJDp
|
7
|
+
XFroixm6HXKe+azptngzrE69sUFO7533lrvUhkfbPHn3JhgPgm1COGqbPJ5V/it7
|
8
|
+
dRsJKuOUeQz3+iC0Jrbz3WP+5RuIuD2m+qyR2RVPf4nCkbxQn9QJX1DpG13NyDMA
|
9
|
+
Qp3em5I5GFhECul/VybmC1+6BnJYwe6EJBv7770AAaf9imWsQkW5oTxuKDsL3Iun
|
10
|
+
+xYgZF1V4Kw8xDiMZOqZYoizhzgQRM180j0emgcDp6owPt/44mEPZX6Y7BhWhBIc
|
11
|
+
cS+fJulXJzUYtSl6wZqEvMQzHfYXGO4Q1GtNeTrF8wOoevwmpwo+D42sbVUCAwEA
|
12
|
+
AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
|
13
|
+
FGjIj2OhmYxPWPibGOIXv3Eq7RWZMB8GA1UdIwQYMBaAFGjIj2OhmYxPWPibGOIX
|
14
|
+
v3Eq7RWZMA0GCSqGSIb3DQEBCwUAA4IBAQBITdjp9RtGUKjQqcNLa+WxlhHUUgSv
|
15
|
+
Y2CHTkgG/9LBoe1yCAI0lEMAGOYFFuYc0hsnRSMrrzs7/YTTN4szj+lfUA5EyaSQ
|
16
|
+
KWBzfKBz4t35YOpRBc5v02FfYxtaMfbo5QcN3XjQkApqK8GFQuwEbm8g7eyJiWlI
|
17
|
+
frVg0JwVypg87MWgrPCr0/foRl2zO1d0KG/rssAOJNQy3lrrrGyaaFNRcmGrDxsG
|
18
|
+
59O14d8PCuS7GgaO8DqxirMzRj2PW+kdgNp2+2JTUV7m5Aw6u9yX2rGN+s4zk26P
|
19
|
+
dfdzSpXKHc1Mj7MyxCSFk51nIhtwx+VsYQeS53RWoDhm2uSvVT/9+xCU
|
23
20
|
-----END CERTIFICATE-----
|
24
21
|
-----BEGIN CERTIFICATE-----
|
25
|
-
|
22
|
+
MIIDODCCAiCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADA8MQswCQYDVQQGEwJKUDES
|
26
23
|
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
27
|
-
|
24
|
+
DTI1MDIxMjA4NDIzMVoXDTM0MDIxMDA4NDIzMVowPzELMAkGA1UEBhMCSlAxEjAQ
|
28
25
|
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
uY/bPeOBYiVsOYVe
|
26
|
+
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALmNNo+I5XkgbBTJbvKgJxq5
|
27
|
+
oiJMEInr64KiCJOsA5Z35oE25a8OIWeRqxKW+jufonF96V/swWNM11gaUcTjYT72
|
28
|
+
g66ux42vWNN8uFxhhqhYRyiMjfSVA3HUZFaqmU9WP7H3YQGINJZ83BPOYoinZXEP
|
29
|
+
TrQVa8wIKT9Xc5gOq7+SqUuqLvs4jIkgrB744Fo0soCh5WT3V3Op/5K8MA0+N3P4
|
30
|
+
VrFm/SP8k7deT3EtT/aOHgkaKLo3hQ8zkDegVFEKfmWyoA/MwTSciioX/ePm7jjb
|
31
|
+
z4ffl5/ifg3Hgmuk6m85ZaGULJHCkciEgP8scZUNHkRvDK6ZBluwrUpepv5ARUsC
|
32
|
+
AwEAAaNCMEAwHQYDVR0OBBYEFErc4GxPO8mVXXhTgje5yLxWLh0bMA4GA1UdDwEB
|
33
|
+
/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCAcHOU
|
34
|
+
nvhuV6Vuh4gNZjeLJWapJBVYZdkAOd4EhiWtYpq0wWSqlgE+VzIXV9gccYaulVmf
|
35
|
+
NJoLuenzML764U8kOBk8mOWg+U5AYOXwRgsU+e56jgWG6/ijLSf7YfaVkVZNPe36
|
36
|
+
59+0KLag6AkkeDOdXbkfageukg6LhTk4Zg1piRMP3JSYbXVzTlgdm8hLKgPOJitQ
|
37
|
+
FdjMytGYCU5oGHrRrwhlar0xlIvynzVL5wlkuJ19hKUw4UYjoNFy3ZJtbtdqSaF2
|
38
|
+
ZGX/8KNDYFoHAyvGZCYTr22T1ywWeMFQ+4beiYEv2lifVcYIoI0bEA8Pe9i3Egiv
|
39
|
+
9u18A/unCSVLPua1
|
44
40
|
-----END CERTIFICATE-----
|
data/test/ca.cert
CHANGED
@@ -1,23 +1,20 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
|
2
|
+
MIIDVjCCAj6gAwIBAgIBATANBgkqhkiG9w0BAQsFADA8MQswCQYDVQQGEwJKUDES
|
3
3
|
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
4
|
-
|
4
|
+
DTI1MDIxMjA4NDIzMVoXDTM1MDIxMDA4NDIzMVowPDELMAkGA1UEBhMCSlAxEjAQ
|
5
5
|
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
|
21
|
-
PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
|
22
|
-
d/xgcK06UVQRL/HbEYGiQL056mc=
|
6
|
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJqxQwHle/gAbPM1QabhCqWiAJDp
|
7
|
+
XFroixm6HXKe+azptngzrE69sUFO7533lrvUhkfbPHn3JhgPgm1COGqbPJ5V/it7
|
8
|
+
dRsJKuOUeQz3+iC0Jrbz3WP+5RuIuD2m+qyR2RVPf4nCkbxQn9QJX1DpG13NyDMA
|
9
|
+
Qp3em5I5GFhECul/VybmC1+6BnJYwe6EJBv7770AAaf9imWsQkW5oTxuKDsL3Iun
|
10
|
+
+xYgZF1V4Kw8xDiMZOqZYoizhzgQRM180j0emgcDp6owPt/44mEPZX6Y7BhWhBIc
|
11
|
+
cS+fJulXJzUYtSl6wZqEvMQzHfYXGO4Q1GtNeTrF8wOoevwmpwo+D42sbVUCAwEA
|
12
|
+
AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
|
13
|
+
FGjIj2OhmYxPWPibGOIXv3Eq7RWZMB8GA1UdIwQYMBaAFGjIj2OhmYxPWPibGOIX
|
14
|
+
v3Eq7RWZMA0GCSqGSIb3DQEBCwUAA4IBAQBITdjp9RtGUKjQqcNLa+WxlhHUUgSv
|
15
|
+
Y2CHTkgG/9LBoe1yCAI0lEMAGOYFFuYc0hsnRSMrrzs7/YTTN4szj+lfUA5EyaSQ
|
16
|
+
KWBzfKBz4t35YOpRBc5v02FfYxtaMfbo5QcN3XjQkApqK8GFQuwEbm8g7eyJiWlI
|
17
|
+
frVg0JwVypg87MWgrPCr0/foRl2zO1d0KG/rssAOJNQy3lrrrGyaaFNRcmGrDxsG
|
18
|
+
59O14d8PCuS7GgaO8DqxirMzRj2PW+kdgNp2+2JTUV7m5Aw6u9yX2rGN+s4zk26P
|
19
|
+
dfdzSpXKHc1Mj7MyxCSFk51nIhtwx+VsYQeS53RWoDhm2uSvVT/9+xCU
|
23
20
|
-----END CERTIFICATE-----
|
data/test/ca.key
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpAIBAAKCAQEAmrFDAeV7+ABs8zVBpuEKpaIAkOlcWuiLGbodcp75rOm2eDOs
|
3
|
+
Tr2xQU7vnfeWu9SGR9s8efcmGA+CbUI4aps8nlX+K3t1Gwkq45R5DPf6ILQmtvPd
|
4
|
+
Y/7lG4i4Pab6rJHZFU9/icKRvFCf1AlfUOkbXc3IMwBCnd6bkjkYWEQK6X9XJuYL
|
5
|
+
X7oGcljB7oQkG/vvvQABp/2KZaxCRbmhPG4oOwvci6f7FiBkXVXgrDzEOIxk6pli
|
6
|
+
iLOHOBBEzXzSPR6aBwOnqjA+3/jiYQ9lfpjsGFaEEhxxL58m6VcnNRi1KXrBmoS8
|
7
|
+
xDMd9hcY7hDUa015OsXzA6h6/CanCj4PjaxtVQIDAQABAoIBACJEnmlvItU/kuMV
|
8
|
+
qyOCus8SYjm32GOzHA1o81kO6pRpeaiLGeKflwK2r9I4pMWbQNvuLyl9nIy78tKt
|
9
|
+
Vr4XAYi52AJd6QVCNKQRofdDf7966RCiWSrrrmk5EkdmFCXicUqNP92OoqYq3h0k
|
10
|
+
rl7IJO3UxkK2DgvW4nOz/jafbCNpX+A3P7u1xeN1iKNn4nWL49im2254mFW/j9c1
|
11
|
+
D2g0pSb1wYAwCvGr3UZy49X9DSOylGuxtItP90mBP2TkD+khyXHNzmAWzsS2TWOK
|
12
|
+
UCXMHvQQcPrVLmu2sziWe63cMi6gIVhziQRpmZm3GW+rUml3j4LfiWUQNqAkJrhU
|
13
|
+
g3pRe0kCgYEA0omMasSzzyZSNBD4mfVfZc+0lEPkgYA/Cxd5+cFtgBi+SouZ+Cb2
|
14
|
+
+kwg0v4B8gIPee5Xrgyngtnb9NVKKrOUGVVWXgaZZbIUdD7Z/KfvecBxeEr52XDa
|
15
|
+
oMJy4Cyh/6ujv6SJc5E12xnfsa5aURdvaA/gqAJVUgd/Vzu866soo8sCgYEAvBif
|
16
|
+
R5xxkxL5d/LELh14petFpGIoXIrdKKwrb4Z/oLMgdMztH4FT0sSj/z22ulwEO8+/
|
17
|
+
fyTA0XPQNcOW+UOc3c4UZ2fluXur5Wht+4ulKomPipv3TG9u82uYoEBdCL3O04ox
|
18
|
+
AZvlfcR4PPxpNQ6jwRHNe7ulH/3hNEpNuZOkT18CgYALM7Rb7fFfQTu4d3qyvmKA
|
19
|
+
CUgjZ2VeGpPAJFSiHE+WNDrTvo/Hq1MSyEAq2ccCuGdYZn0VzqiPBsZ0RXD3yqxD
|
20
|
+
mM3KnPFGfu4lrT5t+gV85edjriGTFzUavp3cHaPU9a31wWxq0Lwb10mWq580l1mf
|
21
|
+
INEkP1OI1MtKuev4Yhf8dwKBgQCD0pW+cEvAkWm4wLDwyMLHNW3nWMuEn+WDHbaL
|
22
|
+
QK2tiBxU/1Gn5NFEQ3/T4AJx9Q8ag+xnRPDFWe8v3tWt9862PDlchxoetiewbVG3
|
23
|
+
GxU0DJhGwiu8q9QMUPn0RWduOuf6pTzXLdTWIZ1K0HNDNfFZ3Aowjz+YfisYpIJ4
|
24
|
+
bpqW7QKBgQDR/IOaV72HxHEvQA9oEbFAPOre8kHCXelDsH7/f1JCcWGNAjCWOdEI
|
25
|
+
uRjO612cTv5m3EvV6qSFmvyqC4zFzX/dZ0H/MLu7WV/9Ed4hzJPFxDh4oQfz7OCp
|
26
|
+
6dYL+ZdpGSTlzf9iC6zL9cExIZTX7alurMvzwUeguVdhILRHtjrKtw==
|
27
|
+
-----END RSA PRIVATE KEY-----
|
data/test/ca.srl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
085BCCD3DDF899479489DF0B996A04A0A1F8C9C9
|