Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

tls_server.rb 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!/usr/bin/env ruby
  2. $:.unshift File.expand_path File.join File.dirname(__FILE__), '../lib'
  3. require 'rubygems'
  4. require 'bundler/setup'
  5. require 'openssl'
  6. require 'socket'
  7. require 'cryptcheck'
  8. ::CryptCheck::Logger.level = ENV['LOG'] || :info
  9. OpenSSL::PKey::EC.send :alias_method, :private?, :private_key?
  10. # [512, 768, 1024, 2048, 3072, 4096].each do |s|
  11. # file = "config/rsa-#{s}.pem"
  12. # unless File.exists? file
  13. # puts :rsa, s
  14. # dh = OpenSSL::PKey::RSA.new s
  15. # File.write file, dh.to_pem
  16. # end
  17. #
  18. # file = "config/dh-#{s}.pem"
  19. # unless File.exists? file
  20. # puts :dh, s
  21. # dh = OpenSSL::PKey::DH.new s
  22. # File.write file, dh.to_pem
  23. # end
  24. # end
  25. # exit
  26. def certificate(key)
  27. CryptCheck::Logger.info 'Generating certificate'
  28. cert = OpenSSL::X509::Certificate.new
  29. cert.version = 2
  30. cert.serial = rand 2**(20*8-1) .. 2**(20*8)
  31. cert.not_before = Time.now
  32. cert.not_after = Time.now + 365*24*60*60
  33. cert.public_key = case key
  34. when OpenSSL::PKey::EC
  35. curve = key.group.curve_name
  36. public = OpenSSL::PKey::EC.new curve
  37. public.public_key = key.public_key
  38. public
  39. else
  40. key.public_key
  41. end
  42. name = OpenSSL::X509::Name.parse 'CN=localhost'
  43. cert.subject = name
  44. cert.issuer = name
  45. extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
  46. extension_factory.subject_certificate = cert
  47. extension_factory.issuer_certificate = cert
  48. cert.add_extension extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
  49. cert.add_extension extension_factory.create_extension 'keyUsage', 'keyEncipherment, dataEncipherment, digitalSignature,nonRepudiation,keyCertSign'
  50. cert.add_extension extension_factory.create_extension 'extendedKeyUsage', 'serverAuth, clientAuth'
  51. cert.add_extension extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
  52. cert.add_extension extension_factory.create_extension 'authorityKeyIdentifier', 'keyid:always'
  53. cert.add_extension extension_factory.create_extension 'subjectAltName', 'DNS:localhost'
  54. cert.add_extension OpenSSL::X509::Extension.new '1.3.6.1.5.5.7.1.24', '0', true
  55. cert.sign key, OpenSSL::Digest::SHA512.new
  56. CryptCheck::Logger.info 'Certificate generated'
  57. cert
  58. end
  59. key = OpenSSL::PKey::RSA.new File.read 'config/rsa-2048.pem'
  60. # key = OpenSSL::PKey::EC.new('prime256v1').generate_key
  61. cert = certificate key
  62. CryptCheck::Logger.info 'Starting server'
  63. context = OpenSSL::SSL::SSLContext.new
  64. #context = OpenSSL::SSL::SSLContext.new :SSLv3
  65. #context = OpenSSL::SSL::SSLContext.new :TLSv1_1
  66. context.cert = cert
  67. context.key = key
  68. context.ciphers = ARGV[0] || 'EECDH+AESGCM'
  69. #dh = OpenSSL::PKey::DH.new File.read 'config/dh-4096.pem'
  70. #context.tmp_dh_callback = proc { dh }
  71. #context.ecdh_curves = CryptCheck::Tls::Server::SUPPORTED_CURVES.join ':'
  72. #context.ecdh_curves = 'secp384r1:secp521r1:sect571r1'
  73. #context.ecdh_curves = 'prime256v1'
  74. #ecdh = OpenSSL::PKey::EC.new('secp384r1').generate_key
  75. #context.tmp_ecdh_callback = proc { ecdh }
  76. host, port = '::', 5000
  77. tcp_server = TCPServer.new host, port
  78. tls_server = OpenSSL::SSL::SSLServer.new tcp_server, context
  79. ::CryptCheck::Logger.info "Server started on #{host}:#{port}"
  80. # ::CryptCheck::Logger.info "Supported ciphers:"
  81. # context.ciphers.each { |c| ::CryptCheck::Logger.info c.first }
  82. loop do
  83. begin
  84. connection = tls_server.accept
  85. method = connection.ssl_version
  86. dh = connection.tmp_key
  87. cipher = connection.cipher
  88. cipher = CryptCheck::Tls::Cipher.new method, cipher.first
  89. states = cipher.states
  90. # p states
  91. # text = %i(critical error warning good perfect best).collect do |s|
  92. # states[s].collect { |t| t.to_s.colorize s }.join ' '
  93. # end.reject &:empty?
  94. # text = []
  95. # text = text.join ' '
  96. # text = ''
  97. dh = dh ? " (#{'PFS'.colorize :good} : #{CryptCheck::Tls.key_to_s dh})" : ''
  98. CryptCheck::Logger.info { "#{cipher}#{dh}" }
  99. data = connection.gets
  100. if data
  101. CryptCheck::Logger.info data
  102. end
  103. connection.puts 'HTTP/1.1 200 OK'
  104. connection.puts 'Strict-Transport-Security: max-age=31536000'
  105. connection.close
  106. rescue OpenSSL::SSL::SSLError, SystemCallError
  107. end
  108. end