您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

helpers.rb 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. $:.unshift File.expand_path File.join File.dirname(__FILE__), '../lib'
  2. require 'rubygems'
  3. require 'bundler/setup'
  4. require 'cryptcheck'
  5. Dir['./spec/**/support/**/*.rb'].sort.each { |f| require f }
  6. CryptCheck::Logger.level = ENV['LOG'] || :none
  7. module Helpers
  8. OpenSSL::PKey::EC.send :alias_method, :private?, :private_key?
  9. def key(name)
  10. open(File.join(File.dirname(__FILE__), 'resources', "#{name}.pem"), 'r') { |f| OpenSSL::PKey.read f }
  11. end
  12. def dh(name)
  13. open(File.join(File.dirname(__FILE__), 'resources', "dh-#{name}.pem"), 'r') { |f| OpenSSL::PKey::DH.new f }
  14. end
  15. def certificate(key, domain)
  16. cert = OpenSSL::X509::Certificate.new
  17. cert.version = 2
  18. cert.serial = rand 2**(20*8-1) .. 2**(20*8)
  19. cert.not_before = Time.now
  20. cert.not_after = cert.not_before + 60*60
  21. cert.public_key = case key
  22. when OpenSSL::PKey::EC
  23. curve = key.group.curve_name
  24. public = OpenSSL::PKey::EC.new curve
  25. public.public_key = key.public_key
  26. public
  27. else
  28. key.public_key
  29. end
  30. name = OpenSSL::X509::Name.parse "CN=#{domain}"
  31. cert.subject = name
  32. cert.issuer = name
  33. extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
  34. extension_factory.subject_certificate = cert
  35. extension_factory.issuer_certificate = cert
  36. cert.add_extension extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
  37. cert.add_extension extension_factory.create_extension 'keyUsage', 'keyEncipherment, dataEncipherment, digitalSignature,nonRepudiation,keyCertSign'
  38. cert.add_extension extension_factory.create_extension 'extendedKeyUsage', 'serverAuth, clientAuth'
  39. cert.add_extension extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
  40. cert.add_extension extension_factory.create_extension 'authorityKeyIdentifier', 'keyid:always'
  41. cert.add_extension extension_factory.create_extension 'subjectAltName', "DNS:#{domain}"
  42. cert.sign key, OpenSSL::Digest::SHA512.new
  43. end
  44. def serv(server, process, &block)
  45. IO.pipe do |stop_pipe_r, stop_pipe_w|
  46. threads = []
  47. mutex = Mutex.new
  48. started = ConditionVariable.new
  49. threads << Thread.start do
  50. mutex.synchronize { started.signal }
  51. loop do
  52. readable, = IO.select [server, stop_pipe_r]
  53. break if readable.include? stop_pipe_r
  54. begin
  55. socket = server.accept
  56. begin
  57. process.call socket if process
  58. ensure
  59. socket.close
  60. end
  61. rescue
  62. end
  63. end
  64. server.close
  65. end
  66. mutex.synchronize { started.wait mutex }
  67. begin
  68. block.call if block
  69. ensure
  70. stop_pipe_w.close
  71. threads.each &:join
  72. end
  73. end
  74. end
  75. def context(key: 'rsa-1024', domain: 'localhost', # Key & certificate
  76. version: :TLSv1_2, ciphers: 'AES128-SHA', # TLS version and ciphers
  77. dh: 1024, ecdh: 'secp256r1') # DHE & ECDHE
  78. key = key key
  79. cert = certificate key, domain
  80. context = OpenSSL::SSL::SSLContext.new version
  81. context.cert = cert
  82. context.key = key
  83. context.ciphers = ciphers
  84. if dh
  85. dh = dh dh
  86. context.tmp_dh_callback = proc { dh }
  87. end
  88. if ecdh
  89. ecdh = key ecdh
  90. context.tmp_ecdh_callback = proc { ecdh }
  91. end
  92. context
  93. end
  94. def tls_serv(key: 'rsa-1024', domain: 'localhost', # Key & certificate
  95. version: :TLSv1_2, ciphers: 'AES128-SHA', # TLS version and ciphers
  96. dh: 1024, ecdh: 'secp256r1', # DHE & ECDHE
  97. host: '127.0.0.1', port: 5000, # Binding
  98. process: nil, &block)
  99. context = context(key: key, domain: domain, version: version, ciphers: ciphers, dh: dh, ecdh: ecdh)
  100. tcp_server = TCPServer.new host, port
  101. tls_server = OpenSSL::SSL::SSLServer.new tcp_server, context
  102. begin
  103. serv tls_server, process, &block
  104. ensure
  105. tls_server.close
  106. tcp_server.close
  107. end
  108. end
  109. def plain_serv(host: '127.0.0.1', port: 5000, process: nil, &block)
  110. tcp_server = TCPServer.new host, port
  111. begin
  112. serv tcp_server, process, &block
  113. ensure
  114. tcp_server.close
  115. end
  116. end
  117. def starttls_serv(key: 'rsa-1024', domain: 'localhost', # Key & certificate
  118. version: :TLSv1_2, ciphers: 'AES128-SHA', # TLS version and ciphers
  119. dh: 1024, ecdh: 'secp256r1', # DHE & ECDHE
  120. host: '127.0.0.1', port: 5000, # Binding
  121. plain_process: nil, process: nil, &block)
  122. context = context(key: key, domain: domain, version: version, ciphers: ciphers, dh: dh, ecdh: ecdh)
  123. tcp_server = TCPServer.new host, port
  124. tls_server = OpenSSL::SSL::SSLServer.new tcp_server, context
  125. tls_server.start_immediately = false
  126. internal_process = proc do |socket|
  127. accept = false
  128. accept = plain_process.call socket if plain_process
  129. if accept
  130. tls_socket = socket.accept
  131. begin
  132. process.call tls_socket if process
  133. ensure
  134. socket.close
  135. end
  136. end
  137. end
  138. begin
  139. serv tls_server, internal_process, &block
  140. ensure
  141. tls_server.close
  142. tcp_server.close
  143. end
  144. end
  145. def grade(grades, host, ip, port)
  146. grades[[host, ip, port]]
  147. end
  148. def expect_grade(grades, host, ip, port, family)
  149. grade = grade grades, host, ip, port
  150. expect(grade).to be_a CryptCheck::Tls::Grade
  151. server = grade.server
  152. expect(server).to be_a CryptCheck::Tls::Server
  153. expect(server.hostname).to eq host
  154. expect(server.ip).to eq ip
  155. expect(server.port).to eq port
  156. expect(server.family).to eq case family
  157. when :ipv4 then
  158. Socket::AF_INET
  159. when :ipv6 then
  160. Socket::AF_INET6
  161. end
  162. [grade, server]
  163. end
  164. def expect_grade_error(grades, host, ip, port, error)
  165. server = grades[[host, ip, port]]
  166. expect(server).to be_a CryptCheck::AnalysisFailure
  167. expect(server.to_s).to eq error
  168. end
  169. end
  170. RSpec.configure do |c|
  171. c.include Helpers
  172. end