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.

cert.rb 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. module CryptCheck
  2. module Tls
  3. class Cert
  4. DEFAULT_CA_DIRECTORIES = [
  5. '/usr/share/ca-certificates/mozilla'
  6. ]
  7. SIGNATURE_ALGORITHMS = %i(md2 mdc2 md4 md5 ripemd160 sha sha1 sha2 rsa dss ecc ghost).freeze
  8. SIGNATURE_ALGORITHMS_X509 = {
  9. 'dsaWithSHA' => %i(sha1 dss),
  10. 'dsaWithSHA1' => %i(sha1 dss),
  11. 'dsaWithSHA1_2' => %i(sha1 dss),
  12. 'dsa_with_SHA224' => %i(sha2 dss),
  13. 'dsa_with_SHA256' => %i(sha2 dss),
  14. 'mdc2WithRSA' => %i(mdc2 rsa),
  15. 'md2WithRSAEncryption' => %i(md2 rsa),
  16. 'md4WithRSAEncryption' => %i(md4, rsa),
  17. 'md5WithRSA' => %i(md5 rsa),
  18. 'md5WithRSAEncryption' => %i(md5 rsa),
  19. 'shaWithRSAEncryption' => %i(sha rsa),
  20. 'sha1WithRSA' => %i(sha1 rsa),
  21. 'sha1WithRSAEncryption' => %i(sha1 rsa),
  22. 'sha224WithRSAEncryption' => %i(sha2 rsa),
  23. 'sha256WithRSAEncryption' => %i(sha2 rsa),
  24. 'sha384WithRSAEncryption' => %i(sha2 rsa),
  25. 'sha512WithRSAEncryption' => %i(sha2 rsa),
  26. 'ripemd160WithRSA' => %i(ripemd160 rsa),
  27. 'ecdsa-with-SHA1' => %i(sha1 ecc),
  28. 'ecdsa-with-SHA224' => %i(sha2 ecc),
  29. 'ecdsa-with-SHA256' => %i(sha2 ecc),
  30. 'ecdsa-with-SHA384' => %i(sha2 ecc),
  31. 'ecdsa-with-SHA512' => %i(sha2 ecc),
  32. 'id_GostR3411_94_with_GostR3410_2001' => %i(ghost),
  33. 'id_GostR3411_94_with_GostR3410_94' => %i(ghost),
  34. 'id_GostR3411_94_with_GostR3410_94_cc' => %i(ghost),
  35. 'id_GostR3411_94_with_GostR3410_2001_cc' => %i(ghost)
  36. }.freeze
  37. WEAK_SIGN = {
  38. critical: %i(mdc2 md2 md4 md5 sha sha1)
  39. }.freeze
  40. SIGNATURE_ALGORITHMS.each do |name|
  41. class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
  42. def #{name}?
  43. SIGNATURE_ALGORITHMS_X509[@cert.signature_algorithm].include? :#{name}
  44. end
  45. RUBY_EVAL
  46. end
  47. def initialize(cert, chain=[])
  48. @cert, @chain = case cert
  49. when ::OpenSSL::X509::Certificate
  50. [cert, chain]
  51. when ::OpenSSL::SSL::SSLSocket
  52. [cert.peer_cert, cert.peer_cert_chain]
  53. end
  54. end
  55. def self.trusted?(cert, chain, roots: DEFAULT_CA_DIRECTORIES)
  56. store = ::OpenSSL::X509::Store.new
  57. store.purpose = ::OpenSSL::X509::PURPOSE_SSL_SERVER
  58. store.add_chains roots
  59. chain.each do |cert|
  60. # Never add other self signed certificates than system CA !
  61. next if cert.subject == cert.issuer
  62. store.add_cert cert rescue nil
  63. end if chain
  64. trusted = store.verify cert
  65. return :trusted if trusted
  66. store.error_string
  67. end
  68. def trusted?(roots: DEFAULT_CA_DIRECTORIES)
  69. Cert.trusted? @cert, @chain, roots: roots
  70. end
  71. def valid?(host)
  72. ::OpenSSL::SSL.verify_certificate_identity @cert, host
  73. end
  74. def fingerprint
  75. ::OpenSSL::Digest::SHA256.hexdigest @cert.to_der
  76. end
  77. def key
  78. @cert.public_key
  79. end
  80. def subject
  81. @cert.subject
  82. end
  83. def serial
  84. @cert.serial
  85. end
  86. def issuer
  87. @cert.issuer
  88. end
  89. include State
  90. CHECKS = WEAK_SIGN.collect do |level, hashes|
  91. hashes.collect do |hash|
  92. ["#{hash}_sign".to_sym, -> (s) { s.send "#{hash}?" }, level]
  93. end
  94. end.flatten(1).freeze
  95. def checks
  96. CHECKS
  97. end
  98. def children
  99. [self.key]
  100. end
  101. end
  102. end
  103. end