Sha256: 02edfdb20c5b0c5e560c5c618faf7de13663483098e50d0d0ae490e344ab5a9b

Contents?: true

Size: 1.72 KB

Versions: 29

Compression:

Stored size: 1.72 KB

Contents

# frozen_string_literal: true

module PagesCore
  # = Digest Verifier
  #
  # ==== Usage
  #
  #   verifier = PagesCore::DigestVerifier.new("super secret!")
  #
  #   digest = verifier.generate("foo")
  #
  #   digest.verify("foo", digest)
  #   # => true
  #   digest.verify("bar", digest)
  #   # => raises PagesCore::Errors::InvalidSignature
  #
  # Credit where credit is due: adapted and simplified from
  # +ActiveSupport::MessageVerifier+, since we don't need to handle
  # arbitrary data structures and ship the serialized data to the client.
  class DigestVerifier
    class InvalidSignatureError < StandardError; end

    def initialize(secret, options = {})
      @secret = secret
      @digest = options[:digest] || "SHA1"
    end

    # Generates a digest for a string.
    def generate(data)
      generate_digest(data)
    end

    # Verifies that <tt>digest</tt> is valid for <tt>data</tt>.
    # Raises a +PagesCore::DigestVerifier::InvalidSignatureError+ error if not.
    def verify(data, digest)
      unless valid_digest?(data, digest)
        raise PagesCore::DigestVerifier::InvalidSignatureError
      end

      true
    end

    private

    def secure_compare(value, other)
      return false unless value.bytesize == other.bytesize

      l = value.unpack "C#{value.bytesize}"

      res = 0
      other.each_byte { |byte| res |= byte ^ l.shift }
      res.zero?
    end

    def generate_digest(data)
      require "openssl" unless defined?(OpenSSL)
      OpenSSL::HMAC.hexdigest(
        OpenSSL::Digest.const_get(@digest).new,
        @secret,
        data
      )
    end

    def valid_digest?(data, digest)
      data.present? &&
        digest.present? &&
        secure_compare(digest, generate_digest(data))
    end
  end
end

Version data entries

29 entries across 29 versions & 1 rubygems

Version Path
pages_core-3.15.5 lib/pages_core/digest_verifier.rb
pages_core-3.15.4 lib/pages_core/digest_verifier.rb
pages_core-3.15.3 lib/pages_core/digest_verifier.rb
pages_core-3.15.2 lib/pages_core/digest_verifier.rb
pages_core-3.15.1 lib/pages_core/digest_verifier.rb
pages_core-3.14.0 lib/pages_core/digest_verifier.rb
pages_core-3.13.0 lib/pages_core/digest_verifier.rb
pages_core-3.12.7 lib/pages_core/digest_verifier.rb
pages_core-3.12.6 lib/pages_core/digest_verifier.rb
pages_core-3.12.5 lib/pages_core/digest_verifier.rb
pages_core-3.12.4 lib/pages_core/digest_verifier.rb
pages_core-3.12.3 lib/pages_core/digest_verifier.rb
pages_core-3.12.2 lib/pages_core/digest_verifier.rb
pages_core-3.12.1 lib/pages_core/digest_verifier.rb
pages_core-3.12.0 lib/pages_core/digest_verifier.rb
pages_core-3.11.3 lib/pages_core/digest_verifier.rb
pages_core-3.11.2 lib/pages_core/digest_verifier.rb
pages_core-3.11.1 lib/pages_core/digest_verifier.rb
pages_core-3.11.0 lib/pages_core/digest_verifier.rb
pages_core-3.10.2 lib/pages_core/digest_verifier.rb