rspec-ssltls 0.0.6 → 0.0.7

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
  SHA1:
3
- metadata.gz: f53f243b2bc3862aad3ac2209d05e2c662b77210
4
- data.tar.gz: 11cf15f123a76a3bf18bcd99222ac8e5ee0371a8
3
+ metadata.gz: 22a5bfa0f3ceeea792d4ea2afaaf3b47602062af
4
+ data.tar.gz: 4a321f42d84d785870a4deef599e9c05a9c78216
5
5
  SHA512:
6
- metadata.gz: 14e405703da16d307ad45a5a6c83973c834e14d100e063fc6588e395fab7b904511757ebd5f864155d571f26a14340d12f1956d09e9c1d7a70d11e8378adccaa
7
- data.tar.gz: b28758a21a282f4aa6b668b3bf6704e8adf7c41bd180a3932faa178c5cb328b9ea312e4d4e01e17e73035bc5a790d8347efa240d1f21a0e0b4968decf4487b02
6
+ metadata.gz: 324e3e06008f554cbd7386958106ce95249a48ed7db37f5cbc2ed2c05e49d42fd2a2a917c2202ff7c867d1fdb5cdd7c813add31da11f0599c8092f6731b79e5e
7
+ data.tar.gz: 57db920d7b9793975f26ba5b99941bdcb6efdb8b386b3d84191c94fa4fb6e5ff6ad3ea3ac44a6b8c0ce682855d4e87c19db036e09e11eab472c58d59613558e0
data/README.md CHANGED
@@ -34,6 +34,11 @@ describe 'www.example.com:443' do
34
34
  is_expected.to have_certificate
35
35
  .subject(CN: '*.example.com').signature_algorithm('sha1WithRSAEncryption')
36
36
  end
37
+ it { is_expected.to have_certificate.verified }
38
+ it do
39
+ is_expected.to have_certificate
40
+ .verified_with(File.read('example.org.cer'))
41
+ end
37
42
  it { is_expected.to support_protocol('TLSv1_2') }
38
43
  it { is_expected.to support_cipher('AES256-SHA').protocol('TLSv1') }
39
44
  it { is_expected.to support_cipher('DES-CBC3-SHA').protocol('SSLv3') }
@@ -4,18 +4,23 @@ require 'time'
4
4
 
5
5
  RSpec::Matchers.define :have_certificate do
6
6
  match do |dest|
7
- @chain_string ||= ''
7
+ @chain_string ||= ''
8
8
  @result_string ||= ''
9
- @chain_number ||= 0
9
+ @chain_number ||= 0
10
10
  uri = URI.parse('https://' + dest)
11
11
  socket = TCPSocket.open(uri.host, uri.port)
12
12
  ssl_context = OpenSSL::SSL::SSLContext.new
13
+ ssl_context.verify_mode = @verify_mode if @verify_mode
14
+ ssl_context.cert_store = @cert_store if @cert_store
13
15
  ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
14
16
  ssl_socket.sync_close = true
15
17
  ssl_socket.connect
16
- @peer_cert = ssl_socket.peer_cert_chain[@chain_number]
18
+ if ssl_socket.peer_cert_chain
19
+ @peer_cert = ssl_socket.peer_cert_chain[@chain_number]
20
+ end
21
+ @verify_result = ssl_socket.verify_result
17
22
  ssl_socket.close
18
- @peer_cert ? valid_cert? : false
23
+ @peer_cert ? valid_cert? && verified_cert? : false
19
24
  end
20
25
 
21
26
  chain :subject do |id|
@@ -32,16 +37,32 @@ RSpec::Matchers.define :have_certificate do
32
37
  RspecSsltls::Util.add_string(@chain_string, "chain[#{n}]")
33
38
  end
34
39
 
40
+ chain :verified do
41
+ @verify_mode = OpenSSL::SSL::VERIFY_PEER
42
+ @cert_store = OpenSSL::X509::Store.new
43
+ @cert_store.set_default_paths
44
+ @chain_string =
45
+ RspecSsltls::Util.add_string(@chain_string, 'verified')
46
+ end
47
+
48
+ chain :verified_with do |c|
49
+ @verify_mode = OpenSSL::SSL::VERIFY_PEER
50
+ @cert_store = OpenSSL::X509::Store.new
51
+ @cert_store.add_file(c)
52
+ @chain_string =
53
+ RspecSsltls::Util.add_string(@chain_string, "verified with #{c}")
54
+ end
55
+
35
56
  chain :valid_at do |t|
36
57
  @chain_string =
37
- RspecSsltls::Util.add_string(@chain_string, "valiid at #{t}")
58
+ RspecSsltls::Util.add_string(@chain_string, "valid at #{t}")
38
59
  @t1 = t
39
60
  @t2 = t
40
61
  end
41
62
 
42
63
  chain :valid_in do |t1, t2|
43
64
  @chain_string = RspecSsltls::Util
44
- .add_string(@chain_string, "valiid in #{t1} - #{t2}")
65
+ .add_string(@chain_string, "valid in #{t1} - #{t2}")
45
66
  @t1 = t1
46
67
  @t2 = t2
47
68
  end
@@ -91,6 +112,17 @@ RSpec::Matchers.define :have_certificate do
91
112
  RspecSsltls::Util.add_string(@chain_string, "#{key} #{kv}", ' ')
92
113
  end
93
114
 
115
+ def verified_cert?
116
+ return true if @verify_mode.nil?
117
+ @result_string += " expected: verified\n"
118
+ if @verify_result == OpenSSL::X509::V_OK
119
+ @result_string += " actual: verified\n"
120
+ else
121
+ @result_string += " actual: unverified(errorcode: #{@verify_result})\n"
122
+ end
123
+ @verify_result == OpenSSL::X509::V_OK
124
+ end
125
+
94
126
  def valid_in?
95
127
  return true unless @t1 && @t2
96
128
  fail 'Input time range is incorrect' if @t2 < @t1
@@ -133,5 +165,7 @@ RSpec::Matchers.define :have_certificate do
133
165
  failure_message_when_negated do
134
166
  s = "expected not to have a certificate#{@chain_string}, but did."
135
167
  s + "\n#{@result_string}"
168
+ .sub(/(expected:)/, 'expected not:')
169
+ .sub(/(actual:)/, 'actual: ')
136
170
  end
137
171
  end
@@ -1,4 +1,4 @@
1
1
  # Easily test your SSL/TLS with RSpec.
2
2
  module RspecSsltls
3
- VERSION = '0.0.6'
3
+ VERSION = '0.0.7'
4
4
  end
@@ -1,44 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'rspec_ssltls'
3
3
 
4
- def stub_ssl_socket(params = nil)
5
- allow(TCPSocket).to receive(:open).and_return(nil)
6
- allow(OpenSSL::SSL::SSLSocket).to receive(:new) do
7
- ssl_socket = double('ssl_socket')
8
- allow(ssl_socket).to receive(:method_missing).and_return(nil)
9
- params.each_pair do |k, v|
10
- allow(ssl_socket).to receive(k).and_return(v)
11
- end if params
12
- ssl_socket
13
- end
14
- end
15
-
16
- # See http://www.ietf.org/rfc/rfc5280.txt 4.1.2.4
17
- # See https://github.com/openssl/openssl/blob/master/crypto/objects/obj_xref.txt
18
-
19
- example_ca_cert_name =
20
- OpenSSL::X509::Name.new([%w(C US),
21
- %w(O Example\ Org.),
22
- %w(OU Example\ Org.\ Div.),
23
- %w(CN ca.example.org)
24
- ])
25
- example_ca_cert = OpenSSL::X509::Certificate.new
26
- example_ca_cert.subject = example_ca_cert_name
27
- example_ca_cert.not_before = Time.utc(0, 0, 0, 1, 10, 2014, nil, nil, nil, nil)
28
- example_ca_cert.not_after = Time.utc(0, 0, 0, 1, 10, 2022, nil, nil, nil, nil)
29
-
30
- example_cert_name =
31
- OpenSSL::X509::Name.new([%w(C JP),
32
- %w(ST Tokyo),
33
- %w(O Example\ Co.,\ Ltd.),
34
- %w(OU Example\ Div.),
35
- %w(CN *.example.com)
36
- ])
37
- example_cert = OpenSSL::X509::Certificate.new
38
- example_cert.subject = example_cert_name
39
- example_cert.issuer = example_ca_cert_name
40
- example_cert.not_before = Time.utc(5, 0, 19, 12, 9, 2014, nil, nil, nil, nil)
41
- example_cert.not_after = Time.utc(0, 0, 0, 1, 10, 2015, nil, nil, nil, nil)
4
+ example_ca_cert, example_cert = prepare_ca_certs
42
5
 
43
6
  describe 'rspec-ssltls matchers' do
44
7
  describe '#have_certificate' do
@@ -49,6 +12,10 @@ describe 'rspec-ssltls matchers' do
49
12
  .and_return('sha1WithRSAEncryption')
50
13
  end
51
14
 
15
+ after :all do
16
+ cleanup_ca_certs
17
+ end
18
+
52
19
  ## Having certificate
53
20
  it 'can evalutate having certificate' do
54
21
  stub_ssl_socket(peer_cert_chain: [nil])
@@ -227,5 +194,45 @@ describe 'rspec-ssltls matchers' do
227
194
  .subject(CN: '*.example.com')
228
195
  .signature_algorithm('sha1WithRSAEncryption')
229
196
  end
197
+
198
+ ## Verified
199
+ it 'can evalutate certificate verified' do
200
+ stub_ssl_socket(peer_cert_chain: [example_cert, example_ca_cert],
201
+ verify_result: OpenSSL::X509::V_OK)
202
+ expect('www.example.com:443').to have_certificate
203
+ .verified
204
+ stub_ssl_socket(peer_cert_chain: nil,
205
+ verify_result: OpenSSL::X509::V_ERR_CERT_REJECTED)
206
+ expect('www.example.com:443').not_to have_certificate
207
+ .verified
208
+ end
209
+
210
+ # show default description
211
+ it do
212
+ stub_ssl_socket(peer_cert_chain: [example_cert],
213
+ verify_result: OpenSSL::X509::V_OK)
214
+ expect('www.example.com:443').to have_certificate
215
+ .verified
216
+ end
217
+
218
+ ## Verified with CA certficate
219
+ it 'can evalutate certificate verified with CA certificate' do
220
+ stub_ssl_socket(peer_cert_chain: [example_cert, example_ca_cert],
221
+ verify_result: OpenSSL::X509::V_OK)
222
+ expect('www.example.com:443').to have_certificate
223
+ .verified_with('tmp/ca_cert.cer')
224
+ stub_ssl_socket(peer_cert_chain: nil,
225
+ verify_result: OpenSSL::X509::V_ERR_CERT_UNTRUSTED)
226
+ expect('www.example.com:443').not_to have_certificate
227
+ .verified_with('tmp/cert.cer')
228
+ end
229
+
230
+ # show default description
231
+ it do
232
+ stub_ssl_socket(peer_cert_chain: [example_cert],
233
+ verify_result: OpenSSL::X509::V_OK)
234
+ expect('www.example.com:443').to have_certificate
235
+ .verified_with('tmp/ca_cert.cer')
236
+ end
230
237
  end
231
238
  end
data/spec/spec_helper.rb CHANGED
@@ -14,6 +14,8 @@ end
14
14
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
15
15
 
16
16
  require 'rspec_ssltls'
17
+ require 'openssl'
18
+ require 'fileutils'
17
19
 
18
20
  def stub_ssl_socket(params = nil)
19
21
  allow(TCPSocket).to receive(:open).and_return(nil)
@@ -26,3 +28,55 @@ def stub_ssl_socket(params = nil)
26
28
  ssl_socket
27
29
  end
28
30
  end
31
+
32
+ def prepare_ca_certs
33
+ example_ca_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
34
+ example_ca_cert = OpenSSL::X509::Certificate.new
35
+ example_ca_cert.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
36
+ example_ca_cert.serial = 1
37
+ example_ca_cert.subject =
38
+ OpenSSL::X509::Name.new([%w(C US),
39
+ %w(O Example\ Org.),
40
+ %w(OU Example\ Org.\ Div.),
41
+ %w(CN ca.example.org)
42
+ ])
43
+ example_ca_cert.issuer = example_ca_cert.subject # self-signed
44
+ example_ca_cert.public_key = example_ca_key.public_key
45
+ example_ca_cert.not_before =
46
+ Time.utc(0, 0, 0, 1, 10, 2014, nil, nil, nil, nil)
47
+ example_ca_cert.not_after =
48
+ Time.utc(0, 0, 0, 1, 10, 2022, nil, nil, nil, nil)
49
+ example_ca_cert.sign(example_ca_key, OpenSSL::Digest::SHA256.new)
50
+
51
+ example_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
52
+ example_cert = OpenSSL::X509::Certificate.new
53
+ example_cert.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
54
+ example_cert.serial = 1
55
+ example_cert.subject =
56
+ OpenSSL::X509::Name.new([%w(C JP),
57
+ %w(ST Tokyo),
58
+ %w(O Example\ Co.,\ Ltd.),
59
+ %w(OU Example\ Div.),
60
+ %w(CN *.example.com)
61
+ ])
62
+ example_cert.issuer = example_ca_cert.subject
63
+ example_cert.public_key = example_key.public_key
64
+ example_cert.not_before =
65
+ Time.utc(5, 0, 19, 12, 9, 2014, nil, nil, nil, nil)
66
+ example_cert.not_after =
67
+ Time.utc(0, 0, 0, 1, 10, 2015, nil, nil, nil, nil)
68
+ example_cert.sign(example_ca_key, OpenSSL::Digest::SHA256.new)
69
+
70
+ FileUtils.mkdir_p('tmp')
71
+ File.open('tmp/ca_cert.key', 'wb') { |f| f.print example_ca_key.to_pem }
72
+ File.open('tmp/ca_cert.cer', 'wb') { |f| f.print example_ca_cert.to_pem }
73
+ File.open('tmp/cert.key', 'wb') { |f| f.print example_key.to_pem }
74
+ File.open('tmp/cert.cer', 'wb') { |f| f.print example_cert.to_pem }
75
+
76
+ [example_ca_cert, example_cert]
77
+ end
78
+
79
+ def cleanup_ca_certs
80
+ %w(tmp/ca_cert.key tmp/ca_cert.cer tmp/cert.key tmp/cert.cer)
81
+ .each { |f| File.delete(f) if File.exist?(f) }
82
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-ssltls
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - OTA Hiroshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-27 00:00:00.000000000 Z
11
+ date: 2014-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec