You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. require 'timeout'
  2. module SSLCheck
  3. class NoSslTlsGrade
  4. attr_reader :server, :score, :grade
  5. def initialize(server)
  6. @server, @score, @grade = server, -1, 'X'
  7. end
  8. end
  9. class Grade
  10. attr_reader :server, :score, :grade, :warning, :success
  11. def initialize(server)
  12. @server = server
  13. protocol_score
  14. key_exchange_score
  15. cipher_strengths_score
  16. @score = @protocol_score*0.3 + @key_exchange_score*0.3 + @cipher_strengths_score*0.4
  17. calculate_grade
  18. warning
  19. success
  20. perfect
  21. end
  22. private
  23. def calculate_grade
  24. @grade = case @score
  25. when 0...20 then 'F'
  26. when 20...35 then 'E'
  27. when 35...50 then 'D'
  28. when 50...65 then 'C'
  29. when 65...80 then 'B'
  30. else 'A'
  31. end
  32. @grade = [@grade, 'B'].max if !@server.tlsv1_2? or @server.key_size < 2048
  33. @grade = [@grade, 'C'].max if @server.des3?
  34. @grade = [@grade, 'E'].max if @server.rc4? or @server.des?
  35. @grade = [@grade, 'F'].max if @server.ssl? or @server.key_size < 1024
  36. @grade = 'M' unless @server.cert_valid
  37. @grade = 'T' unless @server.cert_trusted
  38. end
  39. def warning
  40. @warning = []
  41. @warning << :md5_sig if @server.md5_sig?
  42. @warning << :sha1_sig if @server.sha1_sig?
  43. @warning << :md5 if @server.md5?
  44. #@warning << :sha1 if @server.sha1?
  45. @warning << :rc4 if @server.rc4?
  46. @warning << :des if @server.des?
  47. @warning << :des3 if @server.des3?
  48. end
  49. def success
  50. @success = []
  51. @success << :pfs if @server.pfs_only?
  52. @success << :hsts if @server.hsts?
  53. @success << :hsts_long if @server.hsts_long?
  54. end
  55. ALL_WARNING = %i(md5_sig md5 rc4 des)
  56. ALL_SUCCESS = %i(pfs hsts hsts_long)
  57. def perfect
  58. @grade = 'A+' if @grade == 'A' and (ALL_WARNING & @warning).empty? and (ALL_SUCCESS & @success) == ALL_SUCCESS
  59. end
  60. METHODS_SCORES = { SSLv2: 0, SSLv3: 80, TLSv1: 90, TLSv1_1: 95, TLSv1_2: 100 }
  61. def protocol_score
  62. methods = @server.supported_methods
  63. worst, best = methods[:worst], methods[:best]
  64. @protocol_score = (METHODS_SCORES[worst] + METHODS_SCORES[best]) / 2
  65. end
  66. def key_exchange_score
  67. @key_exchange_score = case @server.key_size
  68. when 0 then 0
  69. when 0...512 then 20
  70. when 512...1024 then 40
  71. when 1024...2048 then 80
  72. when 2048...4096 then 90
  73. else 100
  74. end
  75. end
  76. def cipher_strength_score(cipher_strength)
  77. case cipher_strength
  78. when 0 then 0
  79. when 0...128 then 20
  80. when 128...256 then 80
  81. else 100
  82. end
  83. end
  84. def cipher_strengths_score
  85. strength = @server.cipher_size
  86. worst, best = strength[:min], strength[:max]
  87. @cipher_strengths_score = (cipher_strength_score(worst) + cipher_strength_score(best)) / 2
  88. end
  89. end
  90. end