summaryrefslogtreecommitdiff
path: root/ext/openssl/lib/openssl/digest.rb
blob: c95391195431eabb1fd4ff7d4b543fc77298657a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# frozen_string_literal: true
#--
# = Ruby-space predefined Digest subclasses
#
# = Info
# 'OpenSSL for Ruby 2' project
# Copyright (C) 2002  Michal Rokos <m.rokos@sh.cvut.cz>
# All rights reserved.
#
# = Licence
# This program is licensed under the same licence as Ruby.
# (See the file 'LICENCE'.)
#++

module OpenSSL
  class Digest

    # You can get a list of all algorithms:
    #   openssl list -digest-algorithms

    ALGORITHMS = %w(MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)

    if !OPENSSL_VERSION.include?("LibreSSL") && OPENSSL_VERSION_NUMBER > 0x10101000
      ALGORITHMS.concat %w(BLAKE2b512 BLAKE2s256 SHA3-224 SHA3-256 SHA3-384 SHA3-512)
    end

    ALGORITHMS.freeze

    # Return the hash value computed with _name_ Digest. _name_ is either the
    # long name or short name of a supported digest algorithm.
    #
    # === Examples
    #
    #   OpenSSL::Digest.digest("SHA256", "abc")
    #
    # which is equivalent to:
    #
    #   OpenSSL::Digest::SHA256.digest("abc")

    def self.digest(name, data)
      super(data, name)
    end

    ALGORITHMS.each do |name|
      klass = Class.new(self) {
        define_method(:initialize, ->(data = nil) {super(name, data)})
      }

      singleton = (class << klass; self; end)

      singleton.class_eval{
        define_method(:digest) {|data| new.digest(data)}
        define_method(:hexdigest) {|data| new.hexdigest(data)}
      }

      const_set(name.tr('-', '_'), klass)
    end

    # Deprecated.
    #
    # This class is only provided for backwards compatibility.
    # Use OpenSSL::Digest instead.
    class Digest < Digest; end # :nodoc:
    deprecate_constant :Digest

  end # Digest

  # Returns a Digest subclass by _name_
  #
  #   require 'openssl'
  #
  #   OpenSSL::Digest("MD5")
  #   # => OpenSSL::Digest::MD5
  #
  #   Digest("Foo")
  #   # => NameError: wrong constant name Foo

  def Digest(name)
    OpenSSL::Digest.const_get(name)
  end

  module_function :Digest

end # OpenSSL