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.

108 lines
3.2KB

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