소스 검색

Handle corner cases during protocol error

new-scoring
aeris 2 년 전
부모
커밋
c75601dad4

+ 0
- 1
lib/cryptcheck.rb 파일 보기

@@ -87,7 +87,6 @@ module CryptCheck
87 87
 							server.new *a, **kargs
88 88
 						end
89 89
 					ap s.states
90
-					exit
91 90
 					if grade
92 91
 						g = grade.new s
93 92
 						Logger.info { '' }

+ 29
- 9
lib/cryptcheck/tls/engine.rb 파일 보기

@@ -5,7 +5,7 @@ module CryptCheck
5 5
 	module Tls
6 6
 		module Engine
7 7
 			TCP_TIMEOUT = 10
8
-			SSL_TIMEOUT = 2*TCP_TIMEOUT
8
+			TLS_TIMEOUT = 2*TCP_TIMEOUT
9 9
 
10 10
 			class TLSException < ::StandardError
11 11
 			end
@@ -21,13 +21,25 @@ module CryptCheck
21 21
 			class InappropriateFallback < TLSException
22 22
 			end
23 23
 			class Timeout < ::StandardError
24
+				def initialize(ip, port)
25
+					@message = "Timeout when connecting to #{ip}:#{port} (max #{TCP_TIMEOUT.humanize})"
26
+				end
27
+
28
+				def to_s
29
+					@message
30
+				end
24 31
 			end
25 32
 			class TLSTimeout < Timeout
33
+				def initialize(ip, port)
34
+					@message = "Timeout when TLS connecting to #{ip}:#{port} (max #{TLS_TIMEOUT.humanize})"
35
+				end
26 36
 			end
27 37
 			class ConnectionError < ::StandardError
28 38
 			end
29 39
 
30
-			attr_reader :certs, :keys, :dh, :supported_methods, :supported_ciphers, :supported_curves, :curves_preference
40
+			attr_reader :hostname, :ip, :family, :port, :certs, :keys, :dh,
41
+						:supported_methods, :supported_ciphers,
42
+						:supported_curves, :curves_preference
31 43
 
32 44
 			def initialize(hostname, ip, family, port)
33 45
 				@hostname, @ip, @family, @port = hostname, ip, family, port
@@ -64,6 +76,7 @@ module CryptCheck
64 76
 				Logger.info { '' }
65 77
 				Logger.info { 'Supported methods' }
66 78
 				@supported_methods = Method.select { |m| supported_method? m }
79
+				raise TLSNotAvailableException if @supported_methods.empty?
67 80
 			end
68 81
 
69 82
 			def supported_cipher?(method, cipher)
@@ -310,12 +323,14 @@ module CryptCheck
310 323
 					block_given? ? block.call(socket) : nil
311 324
 				rescue ::IO::WaitReadable
312 325
 					#Logger.trace { "Waiting for read to #{@ip}:#{@port}" }
313
-					raise Timeout, "Timeout when connect to #{@ip}:#{@port} (max #{TCP_TIMEOUT.humanize})" unless IO.select [socket], nil, nil, TCP_TIMEOUT
326
+					raise Timeout.new(@ip, @port) unless IO.select [socket], nil, nil, TCP_TIMEOUT
314 327
 					retry
315 328
 				rescue ::IO::WaitWritable
316 329
 					#Logger.trace { "Waiting for write to #{@ip}:#{@port}" }
317
-					raise Timeout, "Timeout when connect to #{@ip}:#{@port} (max #{TCP_TIMEOUT.humanize})" unless IO.select nil, [socket], nil, TCP_TIMEOUT
330
+					raise Timeout.new(@ip, @port) unless IO.select nil, [socket], nil, TCP_TIMEOUT
318 331
 					retry
332
+				rescue Errno::ECONNREFUSED => e
333
+					raise ConnectionError, e
319 334
 				ensure
320 335
 					socket.close
321 336
 				end
@@ -331,11 +346,11 @@ module CryptCheck
331 346
 					return block_given? ? block.call(ssl_socket) : nil
332 347
 				rescue ::OpenSSL::SSL::SSLErrorWaitReadable
333 348
 					#Logger.trace { "Waiting for SSL read to #{name}" }
334
-					raise TLSTimeout, "Timeout when TLS connect to #{@ip}:#{@port} (max #{SSL_TIMEOUT.humanize})" unless IO.select [ssl_socket], nil, nil, SSL_TIMEOUT
349
+					raise TLSTimeout.new(@ip, @port) unless IO.select [ssl_socket], nil, nil, TLS_TIMEOUT
335 350
 					retry
336 351
 				rescue ::OpenSSL::SSL::SSLErrorWaitWritable
337 352
 					#Logger.trace { "Waiting for SSL write to #{name}" }
338
-					raise TLSTimeout, "Timeout when TLS connect to #{@ip}:#{@port} (max #{SSL_TIMEOUT.humanize})" unless IO.select nil, [ssl_socket], nil, SSL_TIMEOUT
353
+					raise TLSTimeout.new(@ip, @port) unless IO.select nil, [ssl_socket], nil, TLS_TIMEOUT
339 354
 					retry
340 355
 				rescue ::OpenSSL::SSL::SSLError => e
341 356
 					case e.message
@@ -387,10 +402,15 @@ module CryptCheck
387 402
 				end
388 403
 
389 404
 				Logger.trace { "Try method=#{method} / ciphers=#{ciphers} / curves=#{curves} / scsv=#{fallback}" }
390
-				connect do |socket|
391
-					ssl_connect socket, ssl_context, method do |ssl_socket|
392
-						return block_given? ? block.call(ssl_socket) : ssl_socket
405
+				begin
406
+					connect do |socket|
407
+						ssl_connect socket, ssl_context, method do |ssl_socket|
408
+							return block_given? ? block.call(ssl_socket) : ssl_socket
409
+						end
393 410
 					end
411
+				rescue => e
412
+					Logger.trace { "Error occurs : #{e}" }
413
+					raise
394 414
 				end
395 415
 			end
396 416
 

+ 46
- 5
lib/cryptcheck/tls/host.rb 파일 보기

@@ -23,24 +23,65 @@ module CryptCheck
23 23
 		class Host
24 24
 			MAX_ANALYSIS_DURATION = 600
25 25
 
26
-			attr_reader :servers
26
+			attr_reader :servers, :error
27
+
28
+			def initialize(hostname, port)
29
+				@hostname, @port = hostname, port
27 30
 
28
-			def initialize
29 31
 				first    = true
30 32
 				@servers = resolve.collect do |args|
33
+					_, ip, _, _ = args
31 34
 					first ? (first = false) : Logger.info { '' }
32 35
 					result = begin
33 36
 						server = ::Timeout.timeout MAX_ANALYSIS_DURATION do
34 37
 							server(*args)
35 38
 						end
36
-						grade(server)
37
-					rescue Engine::TLSException => e
39
+						grade server
40
+					rescue Engine::TLSException, Engine::ConnectionError, Engine::Timeout => e
38 41
 						AnalysisFailure.new e
39 42
 					rescue ::Timeout::Error
40 43
 						TooLongAnalysis.new
41 44
 					end
42
-					[args, result]
45
+					[[@hostname, ip, @port], result]
43 46
 				end.to_h
47
+			rescue => e
48
+				@error = e
49
+			end
50
+
51
+			def to_json
52
+				JSON.generate(@servers.collect do |host, result|
53
+					hostname, ip, _ = host
54
+					json            = {
55
+							hostname: hostname,
56
+							ip:       ip,
57
+					}
58
+					case result
59
+						when Grade
60
+							json[:result] = result.to_json
61
+						else
62
+							json[:error] = result.message
63
+					end
64
+					json
65
+				end)
66
+			end
67
+
68
+			private
69
+			def resolve
70
+				begin
71
+					ip = IPAddr.new @hostname
72
+					return [[nil, ip.to_s, ip.family]]
73
+				rescue IPAddr::InvalidAddressError
74
+				end
75
+				::Addrinfo.getaddrinfo(@hostname, nil, nil, :STREAM)
76
+						.collect { |a| [@hostname, a.ip_address, a.afamily, @port] }
77
+			end
78
+
79
+			def server(*args)
80
+				TcpServer.new *args
81
+			end
82
+
83
+			def grade(server)
84
+				Grade.new server
44 85
 			end
45 86
 		end
46 87
 	end

+ 2
- 17
lib/cryptcheck/tls/https/host.rb 파일 보기

@@ -2,24 +2,9 @@ module CryptCheck
2 2
 	module Tls
3 3
 		module Https
4 4
 			class Host < Tls::Host
5
-				def initialize(hostname, port=443)
6
-					@hostname, @port = hostname, port
7
-					super()
8
-				end
9
-
10 5
 				private
11
-				def resolve
12
-					begin
13
-						ip = IPAddr.new @hostname
14
-						return [[nil, ip.to_s, ip.family]]
15
-					rescue IPAddr::InvalidAddressError
16
-					end
17
-					::Addrinfo.getaddrinfo(@hostname, nil, nil, :STREAM)
18
-							.collect { |a| [@hostname, a.ip_address, a.afamily] }
19
-				end
20
-
21
-				def server(hostname, ip, family)
22
-					Https::Server.new hostname, ip, family, @port
6
+				def server(*args)
7
+					Https::Server.new *args
23 8
 				end
24 9
 
25 10
 				def grade(server)

+ 1
- 1
lib/cryptcheck/tls/https/server.rb 파일 보기

@@ -19,7 +19,7 @@ module CryptCheck
19 19
 												   {
20 20
 														   follow_redirects: false,
21 21
 														   verify:           false,
22
-														   timeout:          SSL_TIMEOUT,
22
+														   timeout: TLS_TIMEOUT,
23 23
 														   ssl_version:      @supported_methods.first.to_sym,
24 24
 														   ciphers:          Cipher::ALL
25 25
 												   }

+ 0
- 135
spec/cryptcheck/support/analysis.rb 파일 보기

@@ -1,135 +0,0 @@
1
-RSpec.shared_examples :analysis do
2
-	describe '#analyze' do
3
-		it 'return 1 grade with IPv4' do
4
-			grades = server host: '127.0.0.1' do
5
-				analyze '127.0.0.1', 5000
6
-			end
7
-
8
-			expect(grades.size).to be 1
9
-			expect_grade grades, '127.0.0.1', '127.0.0.1', 5000, :ipv4
10
-		end
11
-
12
-		it 'return 1 grade with IPv6' do
13
-			grades = server host: '::1' do
14
-				analyze '::1', 5000
15
-			end
16
-
17
-			expect(grades.size).to be 1
18
-			expect_grade grades, '::1', '::1', 5000, :ipv6
19
-		end
20
-
21
-		it 'return 2 grades with hostname (IPv4 & IPv6)' do
22
-			addresses = %w(127.0.0.1 ::1)
23
-			allow(Addrinfo).to receive(:getaddrinfo).with('localhost', nil, nil, :STREAM) do
24
-				addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
25
-			end
26
-
27
-			grades = server host: '::' do
28
-				analyze 'localhost', 5000
29
-			end
30
-
31
-			expect_grade grades, 'localhost', '127.0.0.1', 5000, :ipv4
32
-			expect_grade grades, 'localhost', '::1', 5000, :ipv6
33
-		end
34
-
35
-		it 'return error if DNS resolution problem' do
36
-			allow(Addrinfo).to receive(:getaddrinfo).with('localhost', nil, nil, :STREAM)
37
-									   .and_raise SocketError, 'getaddrinfo: Name or service not known'
38
-
39
-			grades = server do
40
-				analyze 'localhost', 5000
41
-			end
42
-
43
-			expect_grade_error grades, 'localhost', nil, 5000, 'Unable to resolve localhost'
44
-		end
45
-
46
-		it 'return error if analysis too long' do
47
-			stub_const 'CryptCheck::MAX_ANALYSIS_DURATION', 1
48
-			allow(CryptCheck::Tls::Server).to receive(:new) { sleep 2 }
49
-
50
-			grades = server do
51
-				analyze 'localhost', 5000
52
-			end
53
-
54
-			expect_grade_error grades, 'localhost', '127.0.0.1', 5000,
55
-							   'Too long analysis (max 1 second)'
56
-		end
57
-
58
-		it 'return error if unable to connect' do
59
-			addresses = %w(127.0.0.1 ::1)
60
-			allow(Addrinfo).to receive(:getaddrinfo).with('localhost', nil, nil, :STREAM) do
61
-				addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
62
-			end
63
-
64
-			grades = server host: '::1' do
65
-				analyze 'localhost', 5000
66
-			end
67
-
68
-			expect_grade_error grades, 'localhost', '127.0.0.1', 5000,
69
-							   'Connection refused - connect(2) for 127.0.0.1:5000'
70
-			expect_grade grades, 'localhost', '::1', 5000, :ipv6
71
-		end
72
-
73
-		it 'return error if TCP timeout' do
74
-			stub_const 'CryptCheck::Tls::Server::TCP_TIMEOUT', 1
75
-			addresses = %w(127.0.0.1 ::1)
76
-			allow(Addrinfo).to receive(:getaddrinfo).with('localhost', nil, nil, :STREAM) do
77
-				addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
78
-			end
79
-			original = IO.method :select
80
-			allow(IO).to receive(:select) do |*args, &block|
81
-				socket = [args[0]&.first, args[1]&.first].compact.first
82
-				next nil if socket.is_a?(Socket) && (socket.local_address.afamily == Socket::AF_INET)
83
-				original.call *args, &block
84
-			end
85
-
86
-			grades = server host: '::' do
87
-				analyze 'localhost', 5000
88
-			end
89
-
90
-			expect_grade_error grades, 'localhost', '127.0.0.1', 5000,
91
-							   'Timeout when connect to 127.0.0.1:5000 (max 1 second)'
92
-			expect_grade grades, 'localhost', '::1', 5000, :ipv6
93
-		end
94
-
95
-		it 'return error if TLS timeout' do
96
-			stub_const 'CryptCheck::Tls::Server::SSL_TIMEOUT', 1
97
-			addresses = %w(127.0.0.1 ::1)
98
-			allow(Addrinfo).to receive(:getaddrinfo).with('localhost', nil, nil, :STREAM) do
99
-				addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
100
-			end
101
-			original = IO.method :select
102
-			allow(IO).to receive(:select) do |*args, &block|
103
-				socket = [args[0]&.first, args[1]&.first].compact.first
104
-				next nil if socket.is_a?(OpenSSL::SSL::SSLSocket) && (socket.io.local_address.afamily == Socket::AF_INET)
105
-				original.call *args, &block
106
-			end
107
-
108
-			grades = server host: '::' do
109
-				analyze 'localhost', 5000
110
-			end
111
-
112
-			expect_grade_error grades, 'localhost', '127.0.0.1', 5000,
113
-							   'Timeout when TLS connect to 127.0.0.1:5000 (max 1 second)'
114
-			expect_grade grades, 'localhost', '::1', 5000, :ipv6
115
-		end
116
-
117
-		it 'return error if plain server' do
118
-			stub_const 'CryptCheck::Tls::Server::SSL_TIMEOUT', 1
119
-			addresses = %w(127.0.0.1 ::1)
120
-			allow(Addrinfo).to receive(:getaddrinfo).with('localhost', nil, nil, :STREAM) do
121
-				addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
122
-			end
123
-
124
-			grades = plain_server host: '127.0.0.1' do
125
-				server host: '::1' do
126
-					analyze 'localhost', 5000
127
-				end
128
-			end
129
-
130
-			expect_grade_error grades, 'localhost', '127.0.0.1', 5000,
131
-							   'TLS seems not supported on this server'
132
-			expect_grade grades, 'localhost', '::1', 5000, :ipv6
133
-		end
134
-	end
135
-end

+ 129
- 0
spec/cryptcheck/tls/host_spec.rb 파일 보기

@@ -0,0 +1,129 @@
1
+describe CryptCheck::Tls::Host do
2
+	def host(*args, **kargs)
3
+		do_in_serv *args, **kargs do |host, port|
4
+			CryptCheck::Tls::Host.new host, port
5
+		end
6
+	end
7
+
8
+	def servers(*args, **kargs)
9
+		host(*args, **kargs).servers
10
+	end
11
+
12
+	def error(*args, **kargs)
13
+		host(*args, **kargs).error
14
+	end
15
+
16
+	it 'return 1 grade with IPv4' do
17
+		servers = servers()
18
+		expect(servers.size).to be 1
19
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv4, Helpers::DEFAULT_PORT, :ipv4
20
+	end
21
+
22
+	it 'return 1 grade with IPv6' do
23
+		addresses = [Helpers::DEFAULT_IPv6]
24
+		allow(Addrinfo).to receive(:getaddrinfo).with(Helpers::DEFAULT_HOST, nil, nil, :STREAM) do
25
+			addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
26
+		end
27
+
28
+		servers = servers(host: Helpers::DEFAULT_IPv6)
29
+		expect(servers.size).to be 1
30
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv6, Helpers::DEFAULT_PORT, :ipv6
31
+	end
32
+
33
+	it 'return 2 grades with hostname (IPv4 & IPv6)' do
34
+		addresses = [Helpers::DEFAULT_IPv4, Helpers::DEFAULT_IPv6]
35
+		allow(Addrinfo).to receive(:getaddrinfo).with(Helpers::DEFAULT_HOST, nil, nil, :STREAM) do
36
+			addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
37
+		end
38
+
39
+		servers = servers(host: '::')
40
+		expect(servers.size).to be 2
41
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv4, Helpers::DEFAULT_PORT, :ipv4
42
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv6, Helpers::DEFAULT_PORT, :ipv6
43
+	end
44
+
45
+	it 'return error if DNS resolution problem' do
46
+		allow(Addrinfo).to receive(:getaddrinfo).with(Helpers::DEFAULT_HOST, nil, nil, :STREAM)
47
+								   .and_raise SocketError, 'getaddrinfo: Name or service not known'
48
+
49
+		error = error()
50
+		expect_error error, ::SocketError, 'getaddrinfo: Name or service not known'
51
+	end
52
+
53
+	it 'return error if analysis too long' do
54
+		stub_const 'CryptCheck::Tls::Host::MAX_ANALYSIS_DURATION', 1
55
+		allow_any_instance_of(CryptCheck::Tls::Host).to receive(:server) { sleep 2 }
56
+
57
+		servers = servers()
58
+		expect_grade_error servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv4, Helpers::DEFAULT_PORT,
59
+						   'Too long analysis (max 1 second)'
60
+	end
61
+
62
+	it 'return error if unable to connect' do
63
+		addresses = [Helpers::DEFAULT_IPv4, Helpers::DEFAULT_IPv6]
64
+		allow(Addrinfo).to receive(:getaddrinfo).with(Helpers::DEFAULT_HOST, nil, nil, :STREAM) do
65
+			addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
66
+		end
67
+
68
+		servers = servers(host: Helpers::DEFAULT_IPv6)
69
+		expect_grade_error servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv4, Helpers::DEFAULT_PORT,
70
+						   'Connection refused - connect(2) for 127.0.0.1:15000'
71
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv6, Helpers::DEFAULT_PORT, :ipv6
72
+	end
73
+
74
+	it 'return error if TCP timeout' do
75
+		stub_const 'CryptCheck::Tls::Engine::TCP_TIMEOUT', 1
76
+		addresses = [Helpers::DEFAULT_IPv4, Helpers::DEFAULT_IPv6]
77
+		allow(Addrinfo).to receive(:getaddrinfo).with(Helpers::DEFAULT_HOST, nil, nil, :STREAM) do
78
+			addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
79
+		end
80
+
81
+		original = IO.method :select
82
+		allow(IO).to receive(:select) do |*args, &block|
83
+			socket = [args[0]&.first, args[1]&.first].compact.first
84
+			next nil if socket.is_a?(Socket) && (socket.local_address.afamily == Socket::AF_INET)
85
+			original.call *args, &block
86
+		end
87
+
88
+		servers = servers(host: '::')
89
+		expect_grade_error servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv4, Helpers::DEFAULT_PORT,
90
+						   'Timeout when connecting to 127.0.0.1:15000 (max 1 second)'
91
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv6, Helpers::DEFAULT_PORT, :ipv6
92
+	end
93
+
94
+	it 'return error if TLS timeout' do
95
+		stub_const 'CryptCheck::Tls::Engine::TLS_TIMEOUT', 1
96
+		addresses = [Helpers::DEFAULT_IPv4, Helpers::DEFAULT_IPv6]
97
+		allow(Addrinfo).to receive(:getaddrinfo).with(Helpers::DEFAULT_HOST, nil, nil, :STREAM) do
98
+			addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
99
+		end
100
+
101
+		original = IO.method :select
102
+		allow(IO).to receive(:select) do |*args, &block|
103
+			socket = [args[0]&.first, args[1]&.first].compact.first
104
+			next nil if socket.is_a?(OpenSSL::SSL::SSLSocket) && (socket.io.local_address.afamily == Socket::AF_INET)
105
+			original.call *args, &block
106
+		end
107
+
108
+		servers = servers(host: '::')
109
+		expect_grade_error servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv4, Helpers::DEFAULT_PORT,
110
+						   'Timeout when TLS connecting to 127.0.0.1:15000 (max 1 second)'
111
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv6, Helpers::DEFAULT_PORT, :ipv6
112
+	end
113
+
114
+	it 'return error if plain server' do
115
+		stub_const 'CryptCheck::Tls::ENGINE::TLS_TIMEOUT', 1
116
+		addresses = [Helpers::DEFAULT_IPv4, Helpers::DEFAULT_IPv6]
117
+		allow(Addrinfo).to receive(:getaddrinfo).with(Helpers::DEFAULT_HOST, nil, nil, :STREAM) do
118
+			addresses.collect { |a| Addrinfo.new Socket.sockaddr_in(nil, a) }
119
+		end
120
+
121
+		servers = plain_serv Helpers::DEFAULT_IPv4 do
122
+			servers(host: Helpers::DEFAULT_IPv6)
123
+		end
124
+		expect_grade_error servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv4, Helpers::DEFAULT_PORT,
125
+						   'TLS seems not supported on this server'
126
+		expect_grade servers, Helpers::DEFAULT_HOST, Helpers::DEFAULT_IPv6, Helpers::DEFAULT_PORT, :ipv6
127
+	end
128
+
129
+end

+ 2
- 40
spec/cryptcheck/tls/server_spec.rb 파일 보기

@@ -7,46 +7,8 @@ describe CryptCheck::Tls::Server do
7 7
 		FakeTime.unfreeze
8 8
 	end
9 9
 
10
-	default_parameters       = {
11
-			methods:           %i(TLSv1_2),
12
-			chain:             %w(intermediate ca),
13
-			curves:            %i(prime256v1),
14
-			server_preference: true
15
-	}.freeze
16
-	default_ecdsa_parameters = default_parameters.merge({
17
-																material: [[:ecdsa, :prime256v1]],
18
-																ciphers:  %i(ECDHE-ECDSA-AES128-SHA),
19
-																curves:   %i(prime256v1)
20
-														}).freeze
21
-	default_rsa_parameters   = default_parameters.merge({
22
-																material: [[:rsa, 1024]],
23
-																ciphers:  %i(ECDHE-RSA-AES128-SHA),
24
-																curves:   %i(prime256v1),
25
-																dh:       1024
26
-														}).freeze
27
-	default_mixed_parameters = default_parameters.merge({
28
-																material: [[:ecdsa, :prime256v1], [:rsa, 1024]],
29
-																ciphers:  %i(ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA),
30
-																curves:   %i(prime256v1),
31
-																dh:       1024
32
-														}).freeze
33
-	default_sslv2_parameters = default_parameters.merge({
34
-																methods:  :SSLv2,
35
-																material: [[:rsa, 1024]],
36
-																ciphers:  %i(RC4-MD5),
37
-																chain:    []
38
-														}).freeze
39
-	DEFAULT_PARAMETERS       = { ecdsa: default_ecdsa_parameters.freeze,
40
-								 rsa:   default_rsa_parameters.freeze,
41
-								 mixed: default_mixed_parameters.freeze,
42
-								 sslv2: default_sslv2_parameters.freeze }.freeze
43
-
44
-	def server(type=:ecdsa, **kargs)
45
-		params = DEFAULT_PARAMETERS[type].dup
46
-		params.merge!(kargs) if kargs
47
-		host, port = '127.0.0.1', 15000
48
-		params.merge!({ host: host, port: port })
49
-		tls_serv **params do
10
+	def server(*args, **kargs)
11
+		do_in_serv *args, **kargs do |host, port|
50 12
 			CryptCheck::Tls::TcpServer.new 'localhost', host, ::Socket::PF_INET, port
51 13
 		end
52 14
 	end

+ 58
- 7
spec/helpers.rb 파일 보기

@@ -21,7 +21,9 @@ module Helpers
21 21
 	DEFAULT_MATERIAL = [[:ecdsa, :prime256v1]]
22 22
 	DEFAULT_CHAIN    = %w(intermediate ca)
23 23
 	DEFAULT_HOST     = 'localhost'
24
-	DEFAULT_PORT     = 5000
24
+	DEFAULT_IPv4     = '127.0.0.1'
25
+	DEFAULT_IPv6     = '::1'
26
+	DEFAULT_PORT     = 15000
25 27
 
26 28
 	def key(type, name=nil)
27 29
 		name = if name
@@ -93,7 +95,7 @@ module Helpers
93 95
 		context         = if methods == :SSLv2
94 96
 							  OpenSSL::SSL::SSLContext.new :SSLv2
95 97
 						  else
96
-							  context = OpenSSL::SSL::SSLContext.new
98
+							  context         = OpenSSL::SSL::SSLContext.new
97 99
 							  context.options |= OpenSSL::SSL::OP_NO_SSLv2 unless methods.include? :SSLv2
98 100
 							  context.options |= OpenSSL::SSL::OP_NO_SSLv3 unless methods.include? :SSLv3
99 101
 							  context.options |= OpenSSL::SSL::OP_NO_TLSv1 unless methods.include? :TLSv1
@@ -107,7 +109,7 @@ module Helpers
107 109
 		context.keys             = keys
108 110
 		context.extra_chain_cert = chain unless chain.empty?
109 111
 
110
-		context.ciphers         = ciphers.join ':'
112
+		context.ciphers = ciphers.join ':'
111 113
 		if methods != :SSLv2
112 114
 			context.tmp_dh_callback = proc { dh } if dh
113 115
 			context.ecdh_curves     = curves.join ':' if curves
@@ -116,6 +118,50 @@ module Helpers
116 118
 		context
117 119
 	end
118 120
 
121
+	default_parameters       = {
122
+			methods:           %i(TLSv1_2),
123
+			chain:             %w(intermediate ca),
124
+			curves:            %i(prime256v1),
125
+			server_preference: true
126
+	}.freeze
127
+	default_ecdsa_parameters = default_parameters.merge({
128
+																material: [[:ecdsa, :prime256v1]],
129
+																ciphers:  %i(ECDHE-ECDSA-AES128-SHA),
130
+																curves:   %i(prime256v1)
131
+														}).freeze
132
+	default_rsa_parameters   = default_parameters.merge({
133
+																material: [[:rsa, 1024]],
134
+																ciphers:  %i(ECDHE-RSA-AES128-SHA),
135
+																curves:   %i(prime256v1),
136
+																dh:       1024
137
+														}).freeze
138
+	default_mixed_parameters = default_parameters.merge({
139
+																material: [[:ecdsa, :prime256v1], [:rsa, 1024]],
140
+																ciphers:  %i(ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA),
141
+																curves:   %i(prime256v1),
142
+																dh:       1024
143
+														}).freeze
144
+	default_sslv2_parameters = default_parameters.merge({
145
+																methods:  :SSLv2,
146
+																material: [[:rsa, 1024]],
147
+																ciphers:  %i(RC4-MD5),
148
+																chain:    []
149
+														}).freeze
150
+	DEFAULT_PARAMETERS       = { ecdsa: default_ecdsa_parameters.freeze,
151
+								 rsa:   default_rsa_parameters.freeze,
152
+								 mixed: default_mixed_parameters.freeze,
153
+								 sslv2: default_sslv2_parameters.freeze }.freeze
154
+
155
+	def do_in_serv(type=:ecdsa, **kargs)
156
+		params = DEFAULT_PARAMETERS[type].dup
157
+		host, port = Helpers::DEFAULT_HOST, Helpers::DEFAULT_PORT
158
+		params.merge!({ host: host, port: port })
159
+		params.merge!(kargs) if kargs
160
+		tls_serv **params do
161
+			yield host, port if block_given?
162
+		end
163
+	end
164
+
119 165
 	def tls_serv(host: DEFAULT_HOST, port: DEFAULT_PORT,
120 166
 				 material: DEFAULT_MATERIAL, chain: DEFAULT_CHAIN,
121 167
 				 methods: DEFAULT_METHODS, ciphers: DEFAULT_CIPHERS,
@@ -140,7 +186,7 @@ module Helpers
140 186
 		end
141 187
 	end
142 188
 
143
-	def plain_serv(host='127.0.0.1', port=5000, process: nil, &block)
189
+	def plain_serv(host=DEFAULT_HOST, port=DEFAULT_PORT, process: nil, &block)
144 190
 		tcp_server = TCPServer.new host, port
145 191
 		begin
146 192
 			serv tcp_server, process, &block
@@ -149,10 +195,10 @@ module Helpers
149 195
 		end
150 196
 	end
151 197
 
152
-	def starttls_serv(key: DEFAULT_KEY, domain: 'localhost', # Key & certificate
198
+	def starttls_serv(key: DEFAULT_KEY, domain: DEFAULT_HOST, # Key & certificate
153 199
 					  version: DEFAULT_METHOD, ciphers: DEFAULT_CIPHERS, # TLS version and ciphers
154 200
 					  dh: DEFAULT_DH_SIZE, ecdh: DEFAULT_ECC_CURVE, # DHE & ECDHE
155
-					  host: '127.0.0.1', port: 5000, # Binding
201
+					  host: DEFAULT_HOST, port: DEFAULT_PORT, # Binding
156 202
 					  plain_process: nil, process: nil, &block)
157 203
 		context                      = context(key: key, domain: domain, version: version, ciphers: ciphers, dh: dh, ecdh: ecdh)
158 204
 		tcp_server                   = TCPServer.new host, port
@@ -203,9 +249,14 @@ module Helpers
203 249
 
204 250
 	def expect_grade_error(grades, host, ip, port, error)
205 251
 		server = grades[[host, ip, port]]
206
-		expect(server).to be_a CryptCheck::AnalysisFailure
252
+		expect(server).to be_a CryptCheck::Tls::AnalysisFailure
207 253
 		expect(server.to_s).to eq error
208 254
 	end
255
+
256
+	def expect_error(error, type, message)
257
+		expect(error).to be_a type
258
+		expect(error.message).to eq message
259
+	end
209 260
 end
210 261
 
211 262
 RSpec.configure do |c|

Loading…
취소
저장